Skip to content
Open
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
167 changes: 75 additions & 92 deletions pccm/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,7 @@ def __init__(self,
self.scoped = scoped

def to_string(self) -> str:
scoped_str = ""
if self.scoped:
scoped_str = "class"
scoped_str = "class" if self.scoped else ""
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function EnumClass.to_string refactored with the following changes:

prefix = "enum {} {} {{".format(scoped_str, self.name)
if self.base_type:
prefix = "enum {} {}: {} {{".format(scoped_str, self.name,
Expand Down Expand Up @@ -362,13 +360,12 @@ def to_string(self) -> str:
else:
return "{}{} {} = {};".format(doc, self.type_str, self.name,
self.default)
elif self.default is None:
return "{}{} {}{};".format(doc, self.type_str, self.name,
self.array)
else:
if self.default is None:
return "{}{} {}{};".format(doc, self.type_str, self.name,
self.array)
else:
return "{}{} {}{} = {};".format(doc, self.type_str, self.name,
self.array, self.default)
return "{}{} {}{} = {};".format(doc, self.type_str, self.name,
self.array, self.default)
Comment on lines +363 to +368
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function Member.to_string refactored with the following changes:



class TemplateTypeArgument(object):
Expand Down Expand Up @@ -535,18 +532,10 @@ def unpack(self, args: list) -> str:
return ", ".join(map(str, args))

def _clean_pre_attrs_impl(self, attrs: List[str]):
res_attrs = [] # type: List[str]
for attr in attrs:
if attr not in _HEADER_ONLY_PRE_ATTRS:
res_attrs.append(attr)
return res_attrs
return [attr for attr in attrs if attr not in _HEADER_ONLY_PRE_ATTRS]
Comment on lines -538 to +535
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function FunctionCode._clean_pre_attrs_impl refactored with the following changes:

This removes the following comments ( why? ):

# type: List[str]


def _clean_post_attrs_impl(self, attrs: List[str]):
res_attrs = [] # type: List[str]
for attr in attrs:
if attr not in _HEADER_ONLY_POST_ATTRS:
res_attrs.append(attr)
return res_attrs
return [attr for attr in attrs if attr not in _HEADER_ONLY_POST_ATTRS]
Comment on lines -545 to +538
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function FunctionCode._clean_post_attrs_impl refactored with the following changes:

This removes the following comments ( why? ):

# type: List[str]


def get_sig(self,
name: str,
Expand All @@ -565,9 +554,8 @@ def get_sig(self,
return_type = self.return_type
if isinstance(meta, (ConstructorMeta, DestructorMeta)):
return_type = ""
else:
if not header_only:
assert self.return_type != "auto" and self.return_type != "decltype(auto)"
elif not header_only:
assert self.return_type not in ["auto", "decltype(auto)"]
Comment on lines -568 to +558
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function FunctionCode.get_sig refactored with the following changes:

fmt = "{ret_type} {name}({args})"
if withpost:
fmt += "{post_attrs}"
Expand Down Expand Up @@ -650,8 +638,7 @@ def get_impl(self, name: str, meta: FunctionMeta, class_name: str = ""):
post_attrs=post_attrs_str)
if pre_attrs_str:
prefix_fmt = pre_attrs_str + " " + prefix_fmt
blocks = [] # List[Union[Block, str]]
blocks.extend(self._blocks)
blocks = list(self._blocks)
Comment on lines -653 to +641
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function FunctionCode.get_impl refactored with the following changes:

This removes the following comments ( why? ):

# List[Union[Block, str]]

block = Block(template_fmt + prefix_fmt, blocks, "}")
if meta.macro_guard is not None:
block = Block("#if {}".format(meta.macro_guard), [block], "#endif")
Expand Down Expand Up @@ -972,15 +959,18 @@ def _assign_overload_flag_to_func_decls(self):
member_decl_count[cpp_func_name] += 1
for decl in self._function_decls:
cpp_func_name = decl.get_function_name()
if isinstance(decl.meta, ExternalFunctionMeta):
if extend_decl_count[cpp_func_name] > 1:
decl.is_overload = True
elif isinstance(decl.meta, StaticMemberFunctionMeta):
if static_member_decl_count[cpp_func_name] > 1:
decl.is_overload = True
elif isinstance(decl.meta, MemberFunctionMeta):
if member_decl_count[cpp_func_name] > 1:
decl.is_overload = True
if (
isinstance(decl.meta, ExternalFunctionMeta)
and extend_decl_count[cpp_func_name] > 1
or not isinstance(decl.meta, ExternalFunctionMeta)
and isinstance(decl.meta, StaticMemberFunctionMeta)
and static_member_decl_count[cpp_func_name] > 1
or not isinstance(decl.meta, ExternalFunctionMeta)
and not isinstance(decl.meta, StaticMemberFunctionMeta)
and isinstance(decl.meta, MemberFunctionMeta)
and member_decl_count[cpp_func_name] > 1
):
decl.is_overload = True
Comment on lines -975 to +973
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function Class._assign_overload_flag_to_func_decls refactored with the following changes:


def add_dependency(self, *no_param_class_cls: Type["Class"]):
# TODO enable name alias for Class
Expand Down Expand Up @@ -1134,7 +1124,7 @@ def get_includes_with_dep(self) -> List[str]:
for d in self.get_common_deps())
return res

def get_parent_class(self): # -> Optional[Type["Class"]]
def get_parent_class(self): # -> Optional[Type["Class"]]
Comment on lines -1137 to +1127
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function Class.get_parent_class refactored with the following changes:

This removes the following comments ( why? ):

# assert not issubclass(mro[1], ParameterizedClass), "you can't inherit a param class."

"""TODO find a better way to check invalid param class inherit
"""
if type(self) is Class:
Expand All @@ -1145,24 +1135,23 @@ def get_parent_class(self): # -> Optional[Type["Class"]]
base = candidates.pop()
if issubclass(base, Class):
cls_meta = get_class_meta(base)
if cls_meta is None:
pccm_base_types.append(base)
if cls_meta is not None and cls_meta.skip_inherit:
candidates.extend(base.__bases__)
else:
if cls_meta.skip_inherit:
candidates.extend(base.__bases__)
else:
pccm_base_types.append(base)
pccm_base_types.append(base)
assert len(pccm_base_types) == 1, "you can only inherit one class."
pccm_base = pccm_base_types[0]
if pccm_base is not Class and base is not ParameterizedClass:
# assert not issubclass(mro[1], ParameterizedClass), "you can't inherit a param class."
if not issubclass(pccm_base, ParameterizedClass):
# you inherit a class. you must set _this_cls_type by self.set_this_class_type(__class__)
msg = (
"you must use self.set_this_class_type(__class__) to init this class type"
" when you inherit pccm.Class")
assert self._this_cls_type is not None, msg
return pccm_base
if (
pccm_base is not Class
and base is not ParameterizedClass
and not issubclass(pccm_base, ParameterizedClass)
):
# you inherit a class. you must set _this_cls_type by self.set_this_class_type(__class__)
msg = (
"you must use self.set_this_class_type(__class__) to init this class type"
" when you inherit pccm.Class")
assert self._this_cls_type is not None, msg
return pccm_base
return None

def get_class_deps(self) -> List[Type["Class"]]:
Expand Down Expand Up @@ -1232,16 +1221,12 @@ def get_code_class_def(
d.to_string() for d in self._members
if d.cls_type is self._this_cls_type
]
parent_class_alias = None # type: Optional[str]
parent = self.get_parent_class()
if parent is not None:
# TODO better way to get alias name
parent_class_alias = parent.__name__
cdef = CodeSectionClassDef(cu_name, dep_alias, self._code_before_class,
parent_class_alias = parent.__name__ if parent is not None else None
return CodeSectionClassDef(cu_name, dep_alias, self._code_before_class,
self._code_after_class, ext_decls, ec_strs,
typedef_strs, sc_strs, member_func_decls,
member_def_strs, parent_class_alias)
return cdef
Comment on lines -1235 to -1244
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function Class.get_code_class_def refactored with the following changes:

This removes the following comments ( why? ):

# TODO better way to get alias name
# type: Optional[str]


def get_common_deps(self) -> List["Class"]:
assert self.graph_inited, "you must build dependency graph before generate code"
Expand Down Expand Up @@ -1304,13 +1289,12 @@ def generate_namespace(self, namespace: str):
if namespace == "":
return [], []
namespace_parts = namespace.split(".")
namespace_before = [] # type: List[str]
namespace_after = [] # type: List[str]
namespace_before = ["namespace {} {{".format(p) for p in namespace_parts]
namespace_after = [
"}} // namespace {}".format(p) for p in namespace_parts[::-1]
]


Comment on lines 1307 to 1297
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function CodeSection.generate_namespace refactored with the following changes:

This removes the following comments ( why? ):

# type: List[str]

for p in namespace_parts:
namespace_before.append("namespace {} {{".format(p))
for p in namespace_parts[::-1]:
namespace_after.append("}} // namespace {}".format(p))
return namespace_before, namespace_after


Expand Down Expand Up @@ -1394,8 +1378,7 @@ def to_block(self) -> Block:
prefix = code_before_cls + [
"struct {class_name} {{".format(class_name=self.class_name)
]
block = Block("\n".join(prefix), class_contents, "};")
return block
return Block("\n".join(prefix), class_contents, "};")
Comment on lines -1397 to +1381
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function CodeSectionClassDef.to_block refactored with the following changes:



class CodeSectionImpl(CodeSection):
Expand Down Expand Up @@ -1438,9 +1421,9 @@ def extract_module_id_of_class(
relative_path = path.relative_to(Path(root))
import_parts = list(relative_path.parts)
import_parts[-1] = relative_path.stem
elif loader.locate_top_package(path) is None:
return None
else:
if loader.locate_top_package(path) is None:
return None
Comment on lines +1424 to -1443
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function extract_module_id_of_class refactored with the following changes:

import_parts = loader.try_capture_import_parts(path, None)
return ".".join(import_parts)

Expand Down Expand Up @@ -1533,35 +1516,35 @@ def _apply_middleware_to_cus(self, uid_to_cu: Dict[str, Class]):
new_uid_to_cu = OrderedDict() # type: Dict[str, Class]
for middleware in self.middlewares:
mw_type = type(middleware)
if isinstance(middleware, ManualClassGenerator):
for k, cu in uid_to_cu.items():
decls_with_meta = [
] # type: List[Tuple[FunctionDecl, MiddlewareMeta]]
members_with_meta = [
] # type: List[Tuple[Member, MiddlewareMeta]]
# TODO only one meta is allowed
for decl in cu._function_decls:
for mw_meta in decl.meta.mw_metas:
if mw_meta.type is mw_type:
decls_with_meta.append((decl, mw_meta))
for member in cu._members:
for mw_meta in member.mw_metas:
if mw_meta.type is mw_type:
members_with_meta.append((member, mw_meta))
if not decls_with_meta and not members_with_meta:
continue
new_pcls = middleware.create_manual_class(cu)
if new_pcls.namespace is None:
new_pcls.namespace = cu.namespace + "." + middleware.subnamespace
for decl, mw_meta in decls_with_meta:
new_pcls.handle_function_decl(cu, decl, mw_meta)
for member, mw_meta in members_with_meta:
new_pcls.handle_member(cu, member, mw_meta)
uid = new_pcls.namespace + "-" + type(new_pcls).__name__
new_uid_to_cu[uid] = new_pcls
else:
if not isinstance(middleware, ManualClassGenerator):
raise NotImplementedError

for k, cu in uid_to_cu.items():
decls_with_meta = [
] # type: List[Tuple[FunctionDecl, MiddlewareMeta]]
members_with_meta = [
] # type: List[Tuple[Member, MiddlewareMeta]]
# TODO only one meta is allowed
for decl in cu._function_decls:
for mw_meta in decl.meta.mw_metas:
if mw_meta.type is mw_type:
decls_with_meta.append((decl, mw_meta))
for member in cu._members:
for mw_meta in member.mw_metas:
if mw_meta.type is mw_type:
members_with_meta.append((member, mw_meta))
if not decls_with_meta and not members_with_meta:
continue
new_pcls = middleware.create_manual_class(cu)
if new_pcls.namespace is None:
new_pcls.namespace = cu.namespace + "." + middleware.subnamespace
for decl, mw_meta in decls_with_meta:
new_pcls.handle_function_decl(cu, decl, mw_meta)
for member, mw_meta in members_with_meta:
new_pcls.handle_member(cu, member, mw_meta)
uid = new_pcls.namespace + "-" + type(new_pcls).__name__
new_uid_to_cu[uid] = new_pcls
Comment on lines -1536 to +1546
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function CodeGenerator._apply_middleware_to_cus refactored with the following changes:


def build_graph(self,
cus: List[Union[Class, ParameterizedClass]],
root: Optional[Union[str, Path]] = None,
Expand Down
12 changes: 5 additions & 7 deletions pccm/core/buildmeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ def _unique_list_keep_order(seq: list):
# https://www.peterbe.com/plog/fastest-way-to-uniquify-a-list-in-python-3.6
# only python 3.7 language std ensure the preserve-order dict
return list(dict.fromkeys(seq))
else:
# https://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-whilst-preserving-order
seen = set()
seen_add = seen.add
return [x for x in seq if not (x in seen or seen_add(x))]
# https://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-whilst-preserving-order
seen = set()
seen_add = seen.add
return [x for x in seq if not (x in seen or seen_add(x))]
Comment on lines -15 to +18
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function _unique_list_keep_order refactored with the following changes:



def _merge_compiler_to_flags(this: Dict[str, List[str]],
Expand Down Expand Up @@ -66,11 +65,10 @@ def __add__(self, other: "BuildMeta"):
merged_ldflags = _merge_compiler_to_flags(self.compiler_to_ldflags,
other.compiler_to_ldflags)

res = BuildMeta(
return BuildMeta(
self.includes + other.includes, self.libpaths + other.libpaths,
_unique_list_keep_order(self.libraries + other.libraries),
merged_cflags, merged_ldflags)
return res
Comment on lines -69 to -73
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function BuildMeta.__add__ refactored with the following changes:


def __radd__(self, other: "BuildMeta"):
return other.__add__(self)
Expand Down
4 changes: 1 addition & 3 deletions pccm/core/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ def generate_code(block: Union[Block, str], start_col_offset: int,
return [col_str + l for l in block_lines]
res = [] # type: List[str]
prefix = block.prefix
next_indent = indent
if block.indent is not None:
next_indent = block.indent
next_indent = block.indent if block.indent is not None else indent
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function generate_code refactored with the following changes:

if prefix:
prefix_lines = prefix.split("\n")
res.extend([col_str + l for l in prefix_lines])
Expand Down
21 changes: 7 additions & 14 deletions pccm/graph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def postorder_traversal(node: Node, node_map: Dict[str, Node]):
if namedio.key not in node_map:
continue
inp = node_map[namedio.key]
if not inp in visited:
if inp not in visited:
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function postorder_traversal refactored with the following changes:

  • Simplify logical expression using De Morgan identities (de-morgan)

next_nodes.append(inp)
ready = False
if ready:
Expand Down Expand Up @@ -112,11 +112,10 @@ def _cycle_detection(node_map: Dict[str, Node], node: Node, visited: Set[str],
def cycle_detection(node_map: Dict[str, Node]):
visited = set()
trace = set()
for node in node_map.values():
if node.key not in visited:
if _cycle_detection(node_map, visited, trace):
return True
return False
return any(
node.key not in visited and _cycle_detection(node_map, visited, trace)
for node in node_map.values()
)
Comment on lines -115 to +118
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function cycle_detection refactored with the following changes:



class Graph(object):
Expand Down Expand Up @@ -177,10 +176,7 @@ def is_source_of(self, lfs: Node, rfs: Node):
def get_sources_of(self, node: Node):
assert not self._has_cycle, "graph must be DAG"
all_sources = set()
stack = []
for inp in node.inputs:
if inp.key in self:
stack.append(self[inp.key])
stack = [self[inp.key] for inp in node.inputs if inp.key in self]
Comment on lines -180 to +179
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function Graph.get_sources_of refactored with the following changes:

while stack:
n = stack.pop()
if n in all_sources:
Expand Down Expand Up @@ -214,10 +210,7 @@ def is_branch_node(self, node: Node):
for io in n.inputs:
if io.key in self:
stack.append(self[io.key])
for s in all_sources:
if s.key in visited:
return True
return False
return any(s.key in visited for s in all_sources)
Comment on lines -217 to +213
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function Graph.is_branch_node refactored with the following changes:

  • Use any() instead of for loop (use-any)



def create_node(key: str, *inputs: List[NamedIO]):
Expand Down
8 changes: 4 additions & 4 deletions pccm/middlewares/expose_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ def create_manual_class(self, cu: Class) -> ManualClass:
return self.singleton

def get_code_units(self) -> List[Class]:
if self.singleton.main_cu is not None:
self.singleton.postprocess()
return [self.singleton]
else:
if self.singleton.main_cu is None:
return []

self.singleton.postprocess()
return [self.singleton]
Comment on lines -66 to +70
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Function ExposeMain.get_code_units refactored with the following changes:



def mark(func=None):
meta = ExposeMainMeta()
Expand Down
Loading