2015-03-30 16:12:51 +00:00
|
|
|
// Copyright 2015 The Prometheus Authors
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2020-02-03 16:23:44 +00:00
|
|
|
package parser
|
2015-03-30 16:12:51 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sort"
|
|
|
|
"strings"
|
2015-11-15 09:26:38 +00:00
|
|
|
"time"
|
2015-03-30 16:12:51 +00:00
|
|
|
|
2015-08-20 15:18:46 +00:00
|
|
|
"github.com/prometheus/common/model"
|
2020-10-22 09:00:08 +00:00
|
|
|
|
2021-11-08 14:23:17 +00:00
|
|
|
"github.com/prometheus/prometheus/model/labels"
|
2015-03-30 16:12:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Tree returns a string of the tree structure of the given node.
|
|
|
|
func Tree(node Node) string {
|
|
|
|
return tree(node, "")
|
|
|
|
}
|
|
|
|
|
|
|
|
func tree(node Node, level string) string {
|
2015-04-29 14:35:18 +00:00
|
|
|
if node == nil {
|
|
|
|
return fmt.Sprintf("%s |---- %T\n", level, node)
|
|
|
|
}
|
2015-03-30 16:12:51 +00:00
|
|
|
typs := strings.Split(fmt.Sprintf("%T", node), ".")[1]
|
|
|
|
|
2018-02-12 12:09:51 +00:00
|
|
|
t := fmt.Sprintf("%s |---- %s :: %s\n", level, typs, node)
|
2015-03-30 16:12:51 +00:00
|
|
|
|
|
|
|
level += " · · ·"
|
|
|
|
|
2019-11-25 11:41:59 +00:00
|
|
|
for _, e := range Children(node) {
|
|
|
|
t += tree(e, level)
|
2015-03-30 16:12:51 +00:00
|
|
|
}
|
2019-11-25 11:41:59 +00:00
|
|
|
|
2015-03-30 16:12:51 +00:00
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
|
|
|
func (node *EvalStmt) String() string {
|
|
|
|
return "EVAL " + node.Expr.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (es Expressions) String() (s string) {
|
|
|
|
if len(es) == 0 {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
for _, e := range es {
|
|
|
|
s += e.String()
|
|
|
|
s += ", "
|
|
|
|
}
|
|
|
|
return s[:len(s)-2]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (node *AggregateExpr) String() string {
|
2022-07-07 12:43:36 +00:00
|
|
|
aggrString := node.getAggOpStr()
|
2018-01-22 10:14:59 +00:00
|
|
|
aggrString += "("
|
2020-02-03 17:48:27 +00:00
|
|
|
if node.Op.IsAggregatorWithParam() {
|
2018-01-22 10:14:59 +00:00
|
|
|
aggrString += fmt.Sprintf("%s, ", node.Param)
|
|
|
|
}
|
|
|
|
aggrString += fmt.Sprintf("%s)", node.Expr)
|
|
|
|
|
2015-03-30 16:12:51 +00:00
|
|
|
return aggrString
|
|
|
|
}
|
|
|
|
|
2024-09-02 20:17:45 +00:00
|
|
|
func (node *AggregateExpr) ShortString() string {
|
|
|
|
aggrString := node.getAggOpStr()
|
|
|
|
return aggrString
|
|
|
|
}
|
|
|
|
|
2022-07-07 12:43:36 +00:00
|
|
|
func (node *AggregateExpr) getAggOpStr() string {
|
|
|
|
aggrString := node.Op.String()
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case node.Without:
|
2024-08-01 14:07:08 +00:00
|
|
|
aggrString += fmt.Sprintf(" without (%s) ", joinLabels(node.Grouping))
|
2022-07-07 12:43:36 +00:00
|
|
|
case len(node.Grouping) > 0:
|
2024-08-01 14:07:08 +00:00
|
|
|
aggrString += fmt.Sprintf(" by (%s) ", joinLabels(node.Grouping))
|
2022-07-07 12:43:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return aggrString
|
|
|
|
}
|
|
|
|
|
2024-08-01 14:07:08 +00:00
|
|
|
func joinLabels(ss []string) string {
|
|
|
|
for i, s := range ss {
|
|
|
|
// If the label is already quoted, don't quote it again.
|
2024-08-28 15:15:42 +00:00
|
|
|
if s[0] != '"' && s[0] != '\'' && s[0] != '`' && !model.IsValidLegacyMetricName(string(model.LabelValue(s))) {
|
2024-08-01 14:07:08 +00:00
|
|
|
ss[i] = fmt.Sprintf("\"%s\"", s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return strings.Join(ss, ", ")
|
|
|
|
}
|
|
|
|
|
2024-09-02 20:17:45 +00:00
|
|
|
func (node *BinaryExpr) returnBool() string {
|
2015-09-09 23:37:05 +00:00
|
|
|
if node.ReturnBool {
|
2024-09-02 20:17:45 +00:00
|
|
|
return " bool"
|
2015-09-09 23:37:05 +00:00
|
|
|
}
|
2024-09-02 20:17:45 +00:00
|
|
|
return ""
|
|
|
|
}
|
2015-09-09 23:37:05 +00:00
|
|
|
|
2024-09-02 20:17:45 +00:00
|
|
|
func (node *BinaryExpr) String() string {
|
2022-07-07 12:43:36 +00:00
|
|
|
matching := node.getMatchingStr()
|
2024-09-02 20:17:45 +00:00
|
|
|
return fmt.Sprintf("%s %s%s%s %s", node.LHS, node.Op, node.returnBool(), matching, node.RHS)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (node *BinaryExpr) ShortString() string {
|
|
|
|
return fmt.Sprintf("%s%s%s", node.Op, node.returnBool(), node.getMatchingStr())
|
2022-07-07 12:43:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (node *BinaryExpr) getMatchingStr() string {
|
2015-03-30 16:12:51 +00:00
|
|
|
matching := ""
|
|
|
|
vm := node.VectorMatching
|
2016-10-19 17:38:26 +00:00
|
|
|
if vm != nil && (len(vm.MatchingLabels) > 0 || vm.On) {
|
2022-07-07 12:43:36 +00:00
|
|
|
vmTag := "ignoring"
|
2016-06-23 16:23:44 +00:00
|
|
|
if vm.On {
|
2022-07-07 12:43:36 +00:00
|
|
|
vmTag = "on"
|
2016-04-21 10:45:06 +00:00
|
|
|
}
|
Prettifier: Add spaces with non-callable keywords (#11005)
* Prettifier: Add spaces with non-callable keywords
I prefer to have a difference between, on one side: functions calls, end(), start(), and on the other side with, without, ignoring, by and group_rrigt, group_left.
The reasoning is that the former ones are not calls, while other are
functions. Additionally, it matches the examples in our documentation.
Signed-off-by: Julien Pivotto <roidelapluie@o11y.eu>
* Fix tests
Signed-off-by: Julien Pivotto <roidelapluie@o11y.eu>
2022-07-14 22:09:56 +00:00
|
|
|
matching = fmt.Sprintf(" %s (%s)", vmTag, strings.Join(vm.MatchingLabels, ", "))
|
2022-07-07 12:43:36 +00:00
|
|
|
|
2016-05-28 17:45:35 +00:00
|
|
|
if vm.Card == CardManyToOne || vm.Card == CardOneToMany {
|
2022-07-07 12:43:36 +00:00
|
|
|
vmCard := "right"
|
2016-05-28 17:45:35 +00:00
|
|
|
if vm.Card == CardManyToOne {
|
2022-07-07 12:43:36 +00:00
|
|
|
vmCard = "left"
|
2016-05-28 17:45:35 +00:00
|
|
|
}
|
Prettifier: Add spaces with non-callable keywords (#11005)
* Prettifier: Add spaces with non-callable keywords
I prefer to have a difference between, on one side: functions calls, end(), start(), and on the other side with, without, ignoring, by and group_rrigt, group_left.
The reasoning is that the former ones are not calls, while other are
functions. Additionally, it matches the examples in our documentation.
Signed-off-by: Julien Pivotto <roidelapluie@o11y.eu>
* Fix tests
Signed-off-by: Julien Pivotto <roidelapluie@o11y.eu>
2022-07-14 22:09:56 +00:00
|
|
|
matching += fmt.Sprintf(" group_%s (%s)", vmCard, strings.Join(vm.Include, ", "))
|
2015-03-30 16:12:51 +00:00
|
|
|
}
|
|
|
|
}
|
2022-07-07 12:43:36 +00:00
|
|
|
return matching
|
2015-03-30 16:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (node *Call) String() string {
|
|
|
|
return fmt.Sprintf("%s(%s)", node.Func.Name, node.Args)
|
|
|
|
}
|
|
|
|
|
2024-09-02 20:17:45 +00:00
|
|
|
func (node *Call) ShortString() string {
|
|
|
|
return node.Func.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
func (node *MatrixSelector) atOffset() (string, string) {
|
2020-01-10 14:25:41 +00:00
|
|
|
// Copy the Vector selector before changing the offset
|
2024-09-02 20:17:45 +00:00
|
|
|
vecSelector := node.VectorSelector.(*VectorSelector)
|
2015-11-15 09:26:38 +00:00
|
|
|
offset := ""
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
switch {
|
|
|
|
case vecSelector.OriginalOffset > time.Duration(0):
|
2021-01-20 10:57:39 +00:00
|
|
|
offset = fmt.Sprintf(" offset %s", model.Duration(vecSelector.OriginalOffset))
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case vecSelector.OriginalOffset < time.Duration(0):
|
2021-02-24 02:16:28 +00:00
|
|
|
offset = fmt.Sprintf(" offset -%s", model.Duration(-vecSelector.OriginalOffset))
|
2015-11-15 09:26:38 +00:00
|
|
|
}
|
2021-01-20 10:57:39 +00:00
|
|
|
at := ""
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
switch {
|
|
|
|
case vecSelector.Timestamp != nil:
|
2021-01-20 10:57:39 +00:00
|
|
|
at = fmt.Sprintf(" @ %.3f", float64(*vecSelector.Timestamp)/1000.0)
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case vecSelector.StartOrEnd == START:
|
2021-02-09 16:03:16 +00:00
|
|
|
at = " @ start()"
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case vecSelector.StartOrEnd == END:
|
2021-02-09 16:03:16 +00:00
|
|
|
at = " @ end()"
|
2021-01-20 10:57:39 +00:00
|
|
|
}
|
2024-09-02 20:17:45 +00:00
|
|
|
return at, offset
|
|
|
|
}
|
2021-01-20 10:57:39 +00:00
|
|
|
|
2024-09-02 20:17:45 +00:00
|
|
|
func (node *MatrixSelector) String() string {
|
|
|
|
at, offset := node.atOffset()
|
|
|
|
// Copy the Vector selector before changing the offset
|
|
|
|
vecSelector := *node.VectorSelector.(*VectorSelector)
|
2021-01-20 10:57:39 +00:00
|
|
|
// Do not print the @ and offset twice.
|
2021-02-09 16:03:16 +00:00
|
|
|
offsetVal, atVal, preproc := vecSelector.OriginalOffset, vecSelector.Timestamp, vecSelector.StartOrEnd
|
2021-01-20 10:57:39 +00:00
|
|
|
vecSelector.OriginalOffset = 0
|
|
|
|
vecSelector.Timestamp = nil
|
2021-02-09 16:03:16 +00:00
|
|
|
vecSelector.StartOrEnd = 0
|
2021-01-20 10:57:39 +00:00
|
|
|
|
|
|
|
str := fmt.Sprintf("%s[%s]%s%s", vecSelector.String(), model.Duration(node.Range), at, offset)
|
2020-01-10 14:25:41 +00:00
|
|
|
|
2021-02-09 16:03:16 +00:00
|
|
|
vecSelector.OriginalOffset, vecSelector.Timestamp, vecSelector.StartOrEnd = offsetVal, atVal, preproc
|
2020-01-10 14:25:41 +00:00
|
|
|
|
2021-01-20 10:57:39 +00:00
|
|
|
return str
|
2015-03-30 16:12:51 +00:00
|
|
|
}
|
|
|
|
|
2024-09-02 20:17:45 +00:00
|
|
|
func (node *MatrixSelector) ShortString() string {
|
|
|
|
at, offset := node.atOffset()
|
|
|
|
return fmt.Sprintf("[%s]%s%s", model.Duration(node.Range), at, offset)
|
|
|
|
}
|
|
|
|
|
2018-12-22 13:47:13 +00:00
|
|
|
func (node *SubqueryExpr) String() string {
|
2022-07-07 12:43:36 +00:00
|
|
|
return fmt.Sprintf("%s%s", node.Expr.String(), node.getSubqueryTimeSuffix())
|
|
|
|
}
|
|
|
|
|
2024-09-02 20:17:45 +00:00
|
|
|
func (node *SubqueryExpr) ShortString() string {
|
|
|
|
return node.getSubqueryTimeSuffix()
|
|
|
|
}
|
|
|
|
|
2022-07-07 12:43:36 +00:00
|
|
|
// getSubqueryTimeSuffix returns the '[<range>:<step>] @ <timestamp> offset <offset>' suffix of the subquery.
|
|
|
|
func (node *SubqueryExpr) getSubqueryTimeSuffix() string {
|
2018-12-22 13:47:13 +00:00
|
|
|
step := ""
|
|
|
|
if node.Step != 0 {
|
2019-01-04 13:47:38 +00:00
|
|
|
step = model.Duration(node.Step).String()
|
2018-12-22 13:47:13 +00:00
|
|
|
}
|
2019-11-26 06:45:51 +00:00
|
|
|
offset := ""
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
switch {
|
|
|
|
case node.OriginalOffset > time.Duration(0):
|
2021-01-20 10:57:39 +00:00
|
|
|
offset = fmt.Sprintf(" offset %s", model.Duration(node.OriginalOffset))
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case node.OriginalOffset < time.Duration(0):
|
2021-02-24 02:16:28 +00:00
|
|
|
offset = fmt.Sprintf(" offset -%s", model.Duration(-node.OriginalOffset))
|
2019-11-26 06:45:51 +00:00
|
|
|
}
|
2021-01-20 10:57:39 +00:00
|
|
|
at := ""
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
switch {
|
|
|
|
case node.Timestamp != nil:
|
2021-01-20 10:57:39 +00:00
|
|
|
at = fmt.Sprintf(" @ %.3f", float64(*node.Timestamp)/1000.0)
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case node.StartOrEnd == START:
|
2021-02-09 16:03:16 +00:00
|
|
|
at = " @ start()"
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case node.StartOrEnd == END:
|
2021-02-09 16:03:16 +00:00
|
|
|
at = " @ end()"
|
2021-01-20 10:57:39 +00:00
|
|
|
}
|
2022-07-07 12:43:36 +00:00
|
|
|
return fmt.Sprintf("[%s:%s]%s%s", model.Duration(node.Range), step, at, offset)
|
2018-12-22 13:47:13 +00:00
|
|
|
}
|
|
|
|
|
2015-03-30 16:12:51 +00:00
|
|
|
func (node *NumberLiteral) String() string {
|
|
|
|
return fmt.Sprint(node.Val)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (node *ParenExpr) String() string {
|
|
|
|
return fmt.Sprintf("(%s)", node.Expr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (node *StringLiteral) String() string {
|
2015-03-30 17:13:36 +00:00
|
|
|
return fmt.Sprintf("%q", node.Val)
|
2015-03-30 16:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (node *UnaryExpr) String() string {
|
|
|
|
return fmt.Sprintf("%s%s", node.Op, node.Expr)
|
|
|
|
}
|
|
|
|
|
2024-09-02 20:17:45 +00:00
|
|
|
func (node *UnaryExpr) ShortString() string {
|
|
|
|
return node.Op.String()
|
|
|
|
}
|
|
|
|
|
2015-03-30 16:12:51 +00:00
|
|
|
func (node *VectorSelector) String() string {
|
2021-09-01 07:48:18 +00:00
|
|
|
var labelStrings []string
|
|
|
|
if len(node.LabelMatchers) > 1 {
|
|
|
|
labelStrings = make([]string, 0, len(node.LabelMatchers)-1)
|
|
|
|
}
|
2015-03-30 16:12:51 +00:00
|
|
|
for _, matcher := range node.LabelMatchers {
|
2024-05-06 09:51:08 +00:00
|
|
|
// Only include the __name__ label if its equality matching and matches the name, but don't skip if it's an explicit empty name matcher.
|
|
|
|
if matcher.Name == labels.MetricName && matcher.Type == labels.MatchEqual && matcher.Value == node.Name && matcher.Value != "" {
|
2015-03-30 16:12:51 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
labelStrings = append(labelStrings, matcher.String())
|
|
|
|
}
|
2015-11-15 09:26:38 +00:00
|
|
|
offset := ""
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
switch {
|
|
|
|
case node.OriginalOffset > time.Duration(0):
|
2021-01-20 10:57:39 +00:00
|
|
|
offset = fmt.Sprintf(" offset %s", model.Duration(node.OriginalOffset))
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case node.OriginalOffset < time.Duration(0):
|
2021-02-24 02:16:28 +00:00
|
|
|
offset = fmt.Sprintf(" offset -%s", model.Duration(-node.OriginalOffset))
|
2021-01-20 10:57:39 +00:00
|
|
|
}
|
|
|
|
at := ""
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
switch {
|
|
|
|
case node.Timestamp != nil:
|
2021-01-20 10:57:39 +00:00
|
|
|
at = fmt.Sprintf(" @ %.3f", float64(*node.Timestamp)/1000.0)
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case node.StartOrEnd == START:
|
2021-02-09 16:03:16 +00:00
|
|
|
at = " @ start()"
|
style: Replace `else if` cascades with `switch`
Wiser coders than myself have come to the conclusion that a `switch`
statement is almost always superior to a statement that includes any
`else if`.
The exceptions that I have found in our codebase are just these two:
* The `if else` is followed by an additional statement before the next
condition (separated by a `;`).
* The whole thing is within a `for` loop and `break` statements are
used. In this case, using `switch` would require tagging the `for`
loop, which probably tips the balance.
Why are `switch` statements more readable?
For one, fewer curly braces. But more importantly, the conditions all
have the same alignment, so the whole thing follows the natural flow
of going down a list of conditions. With `else if`, in contrast, all
conditions but the first are "hidden" behind `} else if `, harder to
spot and (for no good reason) presented differently from the first
condition.
I'm sure the aforemention wise coders can list even more reasons.
In any case, I like it so much that I have found myself recommending
it in code reviews. I would like to make it a habit in our code base,
without making it a hard requirement that we would test on the CI. But
for that, there has to be a role model, so this commit eliminates all
`if else` occurrences, unless it is autogenerated code or fits one of
the exceptions above.
Signed-off-by: beorn7 <beorn@grafana.com>
2023-04-12 14:14:31 +00:00
|
|
|
case node.StartOrEnd == END:
|
2021-02-09 16:03:16 +00:00
|
|
|
at = " @ end()"
|
2015-11-15 09:26:38 +00:00
|
|
|
}
|
2015-03-30 16:12:51 +00:00
|
|
|
|
|
|
|
if len(labelStrings) == 0 {
|
2021-01-20 10:57:39 +00:00
|
|
|
return fmt.Sprintf("%s%s%s", node.Name, at, offset)
|
2015-03-30 16:12:51 +00:00
|
|
|
}
|
|
|
|
sort.Strings(labelStrings)
|
2021-01-20 10:57:39 +00:00
|
|
|
return fmt.Sprintf("%s{%s}%s%s", node.Name, strings.Join(labelStrings, ","), at, offset)
|
2015-03-30 16:12:51 +00:00
|
|
|
}
|