I am looking for a way to make clang-format allow single line empty constructors, but to put braces on the newline everywhere else.
Ideally I want to support these three cases all with one clang config.
Test::Test(const std::string &name) : name(name) {}
std::string Test::get_name()
{
return name;
}
void Test::blank()
{
}
Is there a way to special case constructors in anyway? Even being able to have empty functions on a single line the same as constructors would be acceptable. But putting short functions on a single line is not acceptable.
This doesn't solve all the issues, but it solves my main case.
AllowShortFunctionsOnASingleLine: InlineOnly
This will allow short functions in class definitions to be single line.
From https://clang.llvm.org/docs/ClangFormatStyleOptions.html
SFS_InlineOnly (in configuration: InlineOnly) Only merge functions defined inside a class. Same as “inline”, except it does not implies “empty”: i.e. top level empty functions are not merged either.
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {
}
This combined with BreakBeforeBraces: Allman gives me the desired result.
Related
I noticed that forEach and for in to produce different behavior. I have a list of RegExp and want to run hasMatch on each one. When iterating through the list using forEach, hasMatch never returns true. However, if I use for in, hasMatch returns true.
Sample code:
class Foo {
final str = "Hello";
final regexes = [new RegExp(r"(\w+)")];
String a() {
regexes.forEach((RegExp reg) {
if (reg.hasMatch(str)) {
return 'match';
}
});
return 'no match';
}
String b() {
for (RegExp reg in regexes) {
if (reg.hasMatch(str)) {
return 'match';
}
}
return 'no match';
}
}
void main() {
Foo foo = new Foo();
print(foo.a()); // prints "no match"
print(foo.b()); // prints "match"
}
(DartPad with the above sample code)
The only difference between the methods a and b is that a uses forEach and b uses for in, yet they produce different results. Why is this?
Although there is a prefer_foreach lint, that recommendation is specifically for cases where you can use it with a tear-off (a reference to an existing function). Effective Dart recommends against using Iterable.forEach with anything else, and there is a corresponding avoid_function_literals_in_foreach_calls lint to enforce it.
Except for those simple cases where the callback is a tear-off, Iterable.forEach is not any simpler than using a basic and more general for loop. There are more pitfalls using Iterable.forEach, and this is one of them.
Iterable.forEach is a function that takes a callback as an argument. Iterable.forEach is not a control structure, and the callback is an ordinary function. You therefore cannot use break to stop iterating early or use continue to skip to the next iteration.
A return statement in the callback returns from the callback, and the return value is ignored. The caller of Iterable.forEach will never receive the returned value and will never have an opportunity to propagate it. For example, in:
bool f(List<int> list) {
for (var i in list) {
if (i == 42) {
return true;
}
}
return false;
}
the return true statement returns from the function f and stops iteration. In contrast, with forEach:
bool g(List<int> list) {
list.forEach((i) {
if (i == 42) {
return true;
}
});
return false;
}
the return true statement returns from only the callback. The function g will not return until it completes all iterations and reaches the return false statement at the end. This perhaps is clearer as:
bool callback(int i) {
if (i == 42) {
return true;
}
}
bool g(List<int> list) {
list.forEach(callback);
return false;
}
which makes it more obvious that:
There is no way for callback to cause g to return true.
callback does not return a value along all paths.
(That's the problem you encountered.)
Iterable.forEach must not be used with asynchronous callbacks. Because any value returned by the callback is ignored, asynchronous callbacks can never be waited upon.
I should also point out that if you enable Dart's new null-safety features, which enable stricter type-checking, your forEach code will generate an error because it returns a value in a callback that is expected to have a void return value.
A notable case where Iterable.forEach can be simpler than a regular for loop is if the object you're iterating over might be null:
List<int>? nullableList;
nullableList?.forEach((e) => ...);
whereas a regular for loop would require an additional if check or doing:
List<int>? nullableList;
for (var e in nullableList ?? []) {
...
}
(In JavaScript, for-in has unintuitive pitfalls, so Array.forEach often is recommended instead. Perhaps that's why a lot of people seem to be conditioned to use a .forEach method over a built-in language construct. However, Dart does not share those pitfalls with JavaScript.)
👋 jamesdin! Everything you have shared about the limitations of forEach is correct however there's one part where you are wrong. In the code snippet showing the example of how you the return value from forEach is ignored, you have return true; inside the callback function for forEach which is not allowed as the callback has a return type of void and returning any other value from the callback is not allowed.
Although you have mentioned that returning a value from within the callback will result in an error, I'm just pointing at the code snippet.
Here's the signature for forEach
Also, some more pitfalls of forEach are:
One can't use break or continue statements.
One can't get access to the index of the item as opposed to using the regular for loop
I have taken this function from another mql4 script. The other script compiles absolutely fine with no error. Strangely, now that I have copied this function into my script I get the error } not all control paths return a value
I understand the concept of return a value but not sure when there is a compile difference between the scripts
int ModifyOrder(int ord_ticket,double op, double price,double tp, color mColor)
{
int CloseCnt, err;
CloseCnt=0;
while (CloseCnt < 3)
{
if (OrderModify(ord_ticket,op,price,tp,0,mColor))
{
CloseCnt = 3;
}
else
{
err=GetLastError();
Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err));
if (err>0) CloseCnt++;
}
}
}
Most likely the difference is in #property strict. if using strict mode, you have to redeclare local variables, return value from every function (except void, of course) and some other differences.
In your example the function has to be ended with return CloseCnt; or maybe something else.
No way to declare non-strict mode - simply do not declare the strict one.
Once you declared it, it is applied to that file, and included into other files if importing.
I'm trying to find all method calls and the classes that contain them. If I understand correctly, pattern matches perform backtracking to match in all possible ways.
Take the following java code.
package main;
public class Main {
public static void main(String[] args) {
System.out.println("hello world");
System.out.println("hello again");
}
}
I'm loading the code with createAstsFromDirectory.
rascal>ast = createAstsFromDirectory(|home:///multiple-method-calls|, false);
I'm trying to find both calls to println. The following code matches once:
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case \class(_,_,_,/\methodCall(_,_,str methodName,_)):
println("<methodName>");
}
}
rascal>findCalls(ast);
println
ok
This code matches four times:
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case /\class(_,_,_,/\methodCall(_,_,str methodName,_)):
println("<methodName>");
}
}
rascal>findCalls(ast);
println
println
println
println
ok
How must the pattern look like to match exactly twice?
Related question, how to access the class name? When trying to access the class name I get an error message.
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case /\class(str className,_,_,/\methodCall(_,_,str methodName,_)):
println("<className> <methodName>");
}
}
findCalls(ast);
Main println
|project://personal-prof/src/Assignment13Rules.rsc|(3177,9,<141,16>,<141,25>): Undeclared variable: className
It looks like the first match has className bound correctly to "Main", but the second one does not.
I think I would write this:
void findCalls(set[Declaration] ast) {
for(/class(_, _, _, /methodCall(_,_,str methodName,_)) <- ast) {
println("<methodName>");
}
}
The for loop goes for every class it can find, through every methodCall it can find inside and thus twice for the example you gave.
Your second try goes wrong and matches too often: if you nest a / at the top of the case of a visit, you visit every position in the tree once, and the traverse the entire sub-tree again including the root node again. So you would get each call twice.
Your first try goes wrong because the top-level of a case pattern of a visit does not back-track on itself, it finds the first match for the entire pattern and then stops. So the nested / is only matched once and then the body is executed.
In the for loop solution, the for-loop (unlike the visit) will try all possible matches until it stops, so that's the way to go. There is yet another solution closer to your original plan:
void findCalls(set[Declaration] ast) {
visit (ast) {
case class(_, _, _, body) :
for (/methodCall(_,_,str methodName,_) <- body) {
println("<methodName>");
}
}
}
This also works just like the for loop, it first finds all the classes one-by-one via the visit and then goes through all the nested matches via the for loop.
Finally you could also nest the visit itself to get the right answer:
void findCalls(set[Declaration] ast) {
visit (ast) {
case class(_, _, _, body) :
visit(body) {
case methodCall(_,_,str methodName,_): {
println("<methodName>");
}
}
}
}
WRT to the className thing, it appears that the combination of visit and top-level deep match on a case like so: case /<pattern> there is a bug in the Rasca interpreter with a loss of variable bindings in the deep pattern. So pls avoid that pattern (I don't think you need it), and if you feel like it, submit an issue report on github?
In the for-loop case, this will simply work as expected:
for(/class(str className, _, _, /methodCall(_,_,str methodName,_)) <- ast) {
println("<className>::<methodName>");
}
I'm reasonably proficient with Groovy insofar as my job requires, but not having a background in OOP means that some things still elude me, so apologies if some of the wording is a little off here (feel free to edit if you can make the question clearer).
I'm trying to create an overloaded method where the signature (ideally) differs only in the return type of the single Closure parameter. The Closure contains a method call that returns either an ItemResponse or ListResponse object, both of which could contain an object/objects of any type (which is the type I would like to infer).
The following code is a simplified version of what I'm trying to implement - an error handling method which takes a reference to a service call, safely attempts to resolve it, and returns the item/items from the response as appropriate:
public <T> T testMethod(Closure<ItemResponse<T>> testCall) {
testCall.call().item as T
}
public <T> List<T> testMethod(Closure<ListResponse<T>> testCall) {
testCall.call().items as T
}
Obviously this doesn't work, but is there any alternate approach/workaround that would achieve the desired outcome?
I'm trying to create an overloaded method where the signature
(ideally) differs only in the return type of the single Closure
parameter.
You cannot do that because the return type is not part of the method signature. For example, the following is not valid:
class Demo {
int doit() {}
String doit() {}
}
As mentioned by yourself and #jeffscottbrown, you can't have two methods with the same parameters but different return value. The workaround I can see here is to use a call-back closure. The return value of your testMethod would default to Object and you would provide an "unwrapper" that would the bit after the closure call (extract item or items). Try this out in your GroovyConsole:
class ValueHolder <T> {
T value
}
Closure<List<Integer>> c = {
[1]
}
Closure<ValueHolder<String>> d = {
new ValueHolder(value:'hello world')
}
Closure liu = {List l ->
l.first()
}
Closure vhsu = {ValueHolder vh ->
vh.value
}
// this is the generic method
public <T> Object testMethod(Closure<T> testCall, Closure<T> unwrapper) {
unwrapper(testCall.call()) as T
}
println testMethod(c, liu)
println testMethod(d, vhsu)
It works with both a list or a value holder.
I'm working on a C++ component for Firefox and I'm trying to wrap my mind around XPCOM and all of its parts. It's really confusing so I'm trying to work through it but I'm trying to walk through a page and get all its links. I'm trying to figure out what all the objects do. So if I have this interface:
interface nsIPageSummary : nsISupports {
boolean saveSummary(in nsIDOMDocument document,
out unsigned long numLinks,
out unsigned long numImages);
};
defined in the IDL, the method in my C++ code would look like:
SaveSummary(nsIDOMDocument* inDoc, PRBool* outSuccess)
{
*outSuccess = PR_FALSE;
nsCOMPtr<nsIDOMNodeList> nodeList;
inDoc->GetElementsByTagName(NS_LITERAL_STRING("A"), getter_AddRefs(nodeList));
}
I know the C++ method needs more parameters to match up with the one defined in the interface but I don't understand how all the typing works yet. In terms of the actual list, am I right in understanding that the
inDoc->GetElementsByTagName(NS_LITERAL_STRING("A"), getter_AddRefs(nodeList));
line puts all the "A" tags from the inDoc into the nodeList? And I would just have to walk through nodeList to get them all?
You compile your interface definition using xpidl to get a C++ header file - you can check that file to see how interface definitions are translated. Your method definition should actually look like thit:
nsresult SaveSummary(nsIDOMDocument* inDoc, PRUint32* outNumLinks, PRUint32* outNumImages, PRBool* outSuccess)
I would suggest to use the type PRUint32 instead of the ambiguous unsigned long in the interface definition as well. I would also suggest getting rid of the return value: XPCOM methods always return nsresult which is either NS_OK or an error code, this is enough to indicate success or failure. An error code is automatically translated into an exception when called from JavaScript. And finally I would recommend using lower-case tag names: while it won't matter in HTML (case-insensitive), in an XHTML document only lower-case tag names are accepted. So your interface definition should look like this:
interface nsIPageSummary : nsISupports {
void saveSummary(in nsIDOMDocument document,
out PRUint32 numLinks,
out PRUint32 numImages);
};
And the corresponding implementation:
nsresult
SaveSummary(nsIDOMDocument* inDoc, PRUint32* outNumLinks, PRUint32* outNumImages)
{
nsresult rv;
nsCOMPtr<nsIDOMNodeList> nodeList;
rv = inDoc->GetElementsByTagName(NS_LITERAL_STRING("a"), getter_AddRefs(nodeList));
if (NS_FAILED(rv))
return rv;
rv = nodeList->GetLength(outNumLinks);
if (NS_FAILED(rv))
return rv;
rv = inDoc->GetElementsByTagName(NS_LITERAL_STRING("img"), getter_AddRefs(nodeList));
if (NS_FAILED(rv))
return rv;
rv = nodeList->GetLength(outNumImages);
if (NS_FAILED(rv))
return rv;
return NS_OK;
}