[clang-tools-extra] 0ea2a57 - clangd: Make ompletionModelCodegen.py tpy2.7 compatible
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 18 12:27:10 PDT 2020
Author: Nico Weber
Date: 2020-09-18T15:26:58-04:00
New Revision: 0ea2a57274225066ad81e971659222cf9ee1d12d
URL: https://github.com/llvm/llvm-project/commit/0ea2a57274225066ad81e971659222cf9ee1d12d
DIFF: https://github.com/llvm/llvm-project/commit/0ea2a57274225066ad81e971659222cf9ee1d12d.diff
LOG: clangd: Make ompletionModelCodegen.py tpy2.7 compatible
LLVM still supports Python 2.7, so unbreak bots that still run that.
In a separate commit so that this is easy to revert once we drop
support :)
Added:
Modified:
clang-tools-extra/clangd/quality/CompletionModelCodegen.py
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/quality/CompletionModelCodegen.py b/clang-tools-extra/clangd/quality/CompletionModelCodegen.py
index 8f8234f6ebbc..3fd3872f423d 100644
--- a/clang-tools-extra/clangd/quality/CompletionModelCodegen.py
+++ b/clang-tools-extra/clangd/quality/CompletionModelCodegen.py
@@ -24,25 +24,26 @@ def __init__(self, cpp_class):
def ns_begin(self):
"""Returns snippet for opening namespace declarations."""
- open_ns = [f"namespace {ns} {{" for ns in self.ns]
+ open_ns = ["namespace %s {" % ns for ns in self.ns]
return "\n".join(open_ns)
def ns_end(self):
"""Returns snippet for closing namespace declarations."""
close_ns = [
- f"}} // namespace {ns}" for ns in reversed(self.ns)]
+ "} // namespace %s" % ns for ns in reversed(self.ns)]
return "\n".join(close_ns)
def header_guard(filename):
'''Returns the header guard for the generated header.'''
- return f"GENERATED_DECISION_FOREST_MODEL_{filename.upper()}_H"
+ return "GENERATED_DECISION_FOREST_MODEL_%s_H" % filename.upper()
def boost_node(n, label, next_label):
"""Returns code snippet for a leaf/boost node.
Adds value of leaf to the score and jumps to the root of the next tree."""
- return f"{label}: Score += {n['score']}; goto {next_label};"
+ return "%s: Score += %s; goto %s;" % (
+ label, n['score'], next_label)
def if_greater_node(n, label, next_label):
@@ -52,7 +53,8 @@ def if_greater_node(n, label, next_label):
are represented as IEEE 754, it order-encodes the floats to integers before comparing them.
Control falls through if condition is evaluated to false."""
threshold = n["threshold"]
- return f"{label}: if (E.{n['feature']} >= {order_encode(threshold)} /*{threshold}*/) goto {next_label};"
+ return "%s: if (E.%s >= %s /*%s*/) goto %s;" % (
+ label, n['feature'], order_encode(threshold), threshold, next_label)
def if_member_node(n, label, next_label):
@@ -61,10 +63,11 @@ def if_member_node(n, label, next_label):
described in the node.
Control falls through if condition is evaluated to false."""
members = '|'.join([
- f"BIT({n['feature']}_type::{member})"
+ "BIT(%s_type::%s)" % (n['feature'], member)
for member in n["set"]
])
- return f"{label}: if (E.{n['feature']} & ({members})) goto {next_label};"
+ return "%s: if (E.%s & (%s)) goto %s;" % (
+ label, n['feature'], members, next_label)
def node(n, label, next_label):
@@ -76,7 +79,7 @@ def node(n, label, next_label):
}[n['operation']](n, label, next_label)
-def tree(t, tree_num: int, node_num: int):
+def tree(t, tree_num, node_num):
"""Returns code for inferencing a Decision Tree.
Also returns the size of the decision tree.
@@ -90,20 +93,20 @@ def tree(t, tree_num: int, node_num: int):
immediately next label.
- Leaf node adds the value to the score and jumps to the next tree.
"""
- label = f"t{tree_num}_n{node_num}"
+ label = "t%d_n%d" % (tree_num, node_num)
code = []
if node_num == 0:
- code.append(f"t{tree_num}:")
+ code.append("t%d:" % tree_num)
if t["operation"] == "boost":
- code.append(node(t, label=label, next_label=f"t{tree_num+1}"))
+ code.append(node(t, label=label, next_label="t%d" % (tree_num + 1)))
return code, 1
false_code, false_size = tree(
t['else'], tree_num=tree_num, node_num=node_num+1)
true_node_num = node_num+false_size+1
- true_label = f"t{tree_num}_n{true_node_num}"
+ true_label = "t%d_n%d" % (tree_num, true_node_num)
true_code, true_size = tree(
t['then'], tree_num=tree_num, node_num=true_node_num)
@@ -113,7 +116,7 @@ def tree(t, tree_num: int, node_num: int):
return code+false_code+true_code, 1+false_size+true_size
-def gen_header_code(features_json: list, cpp_class, filename: str):
+def gen_header_code(features_json, cpp_class, filename):
"""Returns code for header declaring the inference runtime.
Declares the Example class named {cpp_class} inside relevant namespaces.
@@ -127,43 +130,46 @@ class can be used to represent a code completion candidate.
if f["kind"] == "NUMBER":
# Floats are order-encoded to integers for faster comparison.
setters.append(
- f"void set{feature}(float V) {{ {feature} = OrderEncode(V); }}")
+ "void set%s(float V) { %s = OrderEncode(V); }" % (
+ feature, feature))
elif f["kind"] == "ENUM":
setters.append(
- f"void set{feature}(unsigned V) {{ {feature} = 1 << V; }}")
+ "void set%s(unsigned V) { %s = 1 << V; }" % (feature, feature))
else:
raise ValueError("Unhandled feature type.", f["kind"])
# Class members represent all the features of the Example.
- class_members = [f"uint32_t {f['name']} = 0;" for f in features_json]
+ class_members = ["uint32_t %s = 0;" % f['name'] for f in features_json]
nline = "\n "
guard = header_guard(filename)
- return f"""#ifndef {guard}
-#define {guard}
+ return """#ifndef %s
+#define %s
#include <cstdint>
-{cpp_class.ns_begin()}
-class {cpp_class.name} {{
+%s
+class %s {
public:
- {nline.join(setters)}
+ %s
private:
- {nline.join(class_members)}
+ %s
// Produces an integer that sorts in the same order as F.
// That is: a < b <==> orderEncode(a) < orderEncode(b).
static uint32_t OrderEncode(float F);
- friend float Evaluate(const {cpp_class.name}&);
-}};
+ friend float Evaluate(const %s&);
+};
-float Evaluate(const {cpp_class.name}&);
-{cpp_class.ns_end()}
-#endif // {guard}
-"""
+float Evaluate(const %s&);
+%s
+#endif // %s
+""" % (guard, guard, cpp_class.ns_begin(), cpp_class.name, nline.join(setters),
+ nline.join(class_members), cpp_class.name, cpp_class.name,
+ cpp_class.ns_end(), guard)
-def order_encode(v: float):
+def order_encode(v):
i = struct.unpack('<I', struct.pack('<f', v))[0]
TopBit = 1 << 31
# IEEE 754 floats compare like sign-magnitude integers.
@@ -172,10 +178,10 @@ def order_encode(v: float):
return TopBit + i # top half of integers
-def evaluate_func(forest_json: list, cpp_class: CppClass):
+def evaluate_func(forest_json, cpp_class):
"""Generates code for `float Evaluate(const {Example}&)` function.
The generated function can be used to score an Example."""
- code = f"float Evaluate(const {cpp_class.name}& E) {{\n"
+ code = "float Evaluate(const %s& E) {\n" % cpp_class.name
lines = []
lines.append("float Score = 0;")
tree_num = 0
@@ -184,48 +190,48 @@ def evaluate_func(forest_json: list, cpp_class: CppClass):
lines.append("")
tree_num += 1
- lines.append(f"t{len(forest_json)}: // No such tree.")
+ lines.append("t%s: // No such tree." % len(forest_json))
lines.append("return Score;")
code += " " + "\n ".join(lines)
code += "\n}"
return code
-def gen_cpp_code(forest_json: list, features_json: list, filename: str,
- cpp_class: CppClass):
+def gen_cpp_code(forest_json, features_json, filename, cpp_class):
"""Generates code for the .cpp file."""
# Headers
# Required by OrderEncode(float F).
angled_include = [
- f'#include <{h}>'
+ '#include <%s>' % h
for h in ["cstring", "limits"]
]
# Include generated header.
- qouted_headers = {f"{filename}.h", "llvm/ADT/bit.h"}
+ qouted_headers = {filename + '.h', 'llvm/ADT/bit.h'}
# Headers required by ENUM features used by the model.
qouted_headers |= {f["header"]
for f in features_json if f["kind"] == "ENUM"}
- quoted_include = [f'#include "{h}"' for h in sorted(qouted_headers)]
+ quoted_include = ['#include "%s"' % h for h in sorted(qouted_headers)]
# using-decl for ENUM features.
- using_decls = "\n".join(f"using {feature['name']}_type = {feature['type']};"
+ using_decls = "\n".join("using %s_type = %s;" % (
+ feature['name'], feature['type'])
for feature in features_json
if feature["kind"] == "ENUM")
nl = "\n"
- return f"""{nl.join(angled_include)}
+ return """%s
-{nl.join(quoted_include)}
+%s
#define BIT(X) (1 << X)
-{cpp_class.ns_begin()}
+%s
-{using_decls}
+%s
-uint32_t {cpp_class.name}::OrderEncode(float F) {{
+uint32_t %s::OrderEncode(float F) {
static_assert(std::numeric_limits<float>::is_iec559, "");
- constexpr uint32_t TopBit = ~(~uint32_t{{0}} >> 1);
+ constexpr uint32_t TopBit = ~(~uint32_t{0} >> 1);
// Get the bits of the float. Endianness is the same as for integers.
uint32_t U = llvm::bit_cast<uint32_t>(F);
@@ -234,11 +240,13 @@ def gen_cpp_code(forest_json: list, features_json: list, filename: str,
if (U & TopBit) // Negative float.
return 0 - U; // Map onto the low half of integers, order reversed.
return U + TopBit; // Positive floats map onto the high half of integers.
-}}
+}
-{evaluate_func(forest_json, cpp_class)}
-{cpp_class.ns_end()}
-"""
+%s
+%s
+""" % (nl.join(angled_include), nl.join(quoted_include), cpp_class.ns_begin(),
+ using_decls, cpp_class.name, evaluate_func(forest_json, cpp_class),
+ cpp_class.ns_end())
def main():
@@ -254,12 +262,12 @@ def main():
output_dir = ns.output_dir
filename = ns.filename
- header_file = f"{output_dir}/{filename}.h"
- cpp_file = f"{output_dir}/{filename}.cpp"
+ header_file = "%s/%s.h" % (output_dir, filename)
+ cpp_file = "%s/%s.cpp" % (output_dir, filename)
cpp_class = CppClass(cpp_class=ns.cpp_class)
- model_file = f"{ns.model}/forest.json"
- features_file = f"{ns.model}/features.json"
+ model_file = "%s/forest.json" % ns.model
+ features_file = "%s/features.json" % ns.model
with open(features_file) as f:
features_json = json.load(f)
More information about the cfe-commits
mailing list