When I run flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/localizations.dart, the generator skips over all Intl.message files that only include a string, printing:
Skipping invalid Intl.message invocation
<Intl.message("MESSAGE")>
reason: The 'args' argument for Intl.message must be specified for messages with parameters. Consider using rewrite_intl_messages.dart
from lib/main.dart line: 125, column: 9
The doc for the internationalization package says The name and args parameters must match the name (or ClassName_methodName) and arguments list of the function respectively. For messages without parameters, both of these can be omitted. But it seems to me that, in this case, my message is without parameters!
Am I misunderstanding what Dart devs mean by parameters?
Move it out of the constructor into a separate function. You can call the function from the constructor, but it has to be a single message alone in a function.
The reason is to support messages with parameters. The translation gets generated, at least conceptually, as a separate function. So we have
foo(String name) => Intl.message('Hello $name', name: 'foo', args: [name]);
in a deferred library fr_FR somewhere
foo(String name) => 'Bonjour $name'
and the implementation of Intl.message is conceptually
currentLanguage.lookup('foo').call(args)
So there can only be one message in a function because we're going to replace that function with something else. And it can't be a constructor because we can't just delegate to that.
Related
I have a small helper proc that is supposed to tell me at compile-time whether a type is an object-type or not.
func isObject*[T](val: typedesc[T]): bool {.compileTime.} = T is (object or ref object)
However, when I call this proc with a simple echo to see whether it works, I receive an error:
type A = object
echo isObject(A)
Error: request to generate code for .compileTime proc: isObject
Why is that? It should be perfectly valid to just call this, isObject should just compile to true and in the end what's written there is echo true, why does this cause this cryptic error?
The problem here is that runtime code (The echo call) is trying to work with a compiletime proc.
That is not valid, as the compiler would not replace the function-call with its result, but try to actually call the function at runtime instead. The compiler knows this is invalid behaviour and thus prohibits it by throwing an error, albeit one that isn't that useful.
The only way this can be allowed is if you store the result of the compile-time proc in a compile-time variable, aka a const. These are allowed to be used at runtime.
So the calling code would look more like this instead:
type A = object
const x = isObject(A)
echo x
EDIT:
As Elegantbeef pointed out on nim's discord:
Another alternative is to just do what I thought would happen initially and have that isObject(A) call evaluate fully at compile-time, so that at runtime it goes away and all that's left is it's result, true.
To do so, just use static:
type A = object
echo static(isObject(A))
I switched to sound null safety and started getting runtime error in a simple assignment, that should never happen with sound null safety:
final widgetOnPressed = widget.onPressed;
Error:
type '(LogData) => void' is not a subtype of type '((LogData?) => void)?'
I can repro it for Flutter versions 2.12.0-4.1.pre and 2.13.0-0.0.pre.505.
PR: https://github.com/flutter/devtools/pull/3971
Failing line: https://github.com/flutter/devtools/blob/9fc560ff2e6749459e2ca6a1dc00bf6fb16ed93b/packages/devtools_app/lib/src/shared/table.dart#L1184
To repro, start DevTools at this PR for macos, connect to an app and click the tab 'Logging'. DevTools will show red screen and error in console.
Is it dart bug or the app bug? If it is the app bug, how can I debug it?
It's a bug in your code.
You didn't say which kind of error you got - a compile-time error or a runtime error. I'm guessing runtime error. (Well, you did say to launch it in the debugger, so that is a good hint too.)
The line final widgetOnPressed = widget.onPressed; looks like it can't possibly fail. After all, the type of the local variable is inferred from the expression assigned to it, and the runtime value of that expression will surely be a subtype of the static type because the type system is sound!
Isn't it? ISN'T IT?
It's not, sorry. Dart 2's type system is mostly sound, even more so with null safety, but class generics is covariant, which can still be unsound. It's fairly hard to hit one of the cases where that unsoundness shows its ugly head, but returning a function where the argument type is the class's type variable is one.
Your state class extends State<TableRow<T?>>, so the widget getter returns a TableRow<T?>. The onPressed of that type has type ItemCallback<T?>?, aka, void Function(T?)?.
You create a _TableRowState<LogData>, with its widget which has static type TableRow<LogData?>, but you somehow manage to pass it a TableRow<LogData> instead. That's fine. Class generics are covariant, so all is apparently fine at compile-time.
Then you do final widgetOnPressed = widget.onPressed;.
The static type of widgetOnPressed is void Function(LogData?) here.
The actual runtime type of onPressed is void Function(LogData) because it's from a TableRow<LogData>.
A void Function(LogData) is-not-a void Function(LogData?) because the former cannot be used in all places where the latter can (in particular, it can't be used in a place where it's called with null).
This assignment is potentially unsound, and actually unsound in this case. The compiler knows this and inserts an extra check to ensure that you don't assign a value to the variable which isn't actually valid. That check triggers and throws the error you see.
How do you avoid that?
Don't create a TableRow<LogData> where a TableRow<LogData?> is required.
Or type the variable as:
final ItemCallback<T>? widgetOnPressed = widget.onPressed;
(no ? on the T).
Or rewrite everything to avoid returning a function with a covariant type parameter (from the class) occurring contra-variantly (as an argument type).
Which solution fits you depends on what you want to be able to do.
I tried to use Tuple in a Jenkinsfile.
The line I wrote is def tupleTest = new Tuple('test', 'test2').
However, Jenkins did not accept this line and keep writing the following error to the console output:
No such constructor found: new groovy.lang.Tuple java.lang.String java.lang.String. Administrators can decide whether to approve or reject this signature.
...
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such constructor found: new groovy.lang.Tuple java.lang.Integer java.lang.String
...
When I visited the "Script Approval" configuration I could not see any scripts that pend approval.
Following this link, I tried to install and enable the "Permissive Security" plugin, but it did not help either - The error was the same.
I even tried to manually add the problematic signature to the scriptApproval.xml file. After I added it, I was able to see it in the list of approved signatures, but the error still remained.
Is there something I am doing wrong?
I had the same issue trying to use tuple on jenkins so I found out that I can simply use a list literal instead:
def tuple = ["test1", "test2"]
which is equivalent to
def (a, b) = ["test1", "test2"]
So now, instead of returning a tuple, I am returning a list in my method
def myMethod(...) {
...
return ["test 1", "test 2"]
}
...
def (a, b) = myMethod(...)
This is more or less a problem caused by groovy.lang.Tuple constructor + Jenkins sandbox Groovy mode. If you take a look at the constructor of this class you will see something like this:
package groovy.lang;
import java.util.AbstractList;
import java.util.List;
public class Tuple extends AbstractList {
private final Object[] contents;
private int hashCode;
public Tuple(Object[] contents) {
if (contents == null) throw new NullPointerException();
this.contents = contents;
}
//....
}
Groovy sandbox mode (enabled by default for all Jenkins pipelines) ensures that every invocation passes script approval check. It's not foolproof, and when it sees new Tuple('a','b') it thinks that the user is looking for a constructor that matches exactly two parameters of type String. And because such constructor does not exists, it throws this exception. However, there are two simple workarounds to this problem.
Use groovy.lang.Tuple2 instead
If your tuple is a pair, then use groovy.lang.Tuple2 instead. The good news about this class is that it provides a constructor that supports two generic types, so it will work in your case.
Use exact Object[] constructor
Alternatively, you can use the exact constructor, e.g
def tuple = new Tuple(["test","test2"] as Object[])
Both options require script approval before you can use them (however, in this case both constructors appear in the in-process script approval page).
I am making use of MarkLogic's ability to call XQuery functions in the XSL transform.
Let's say I have an XQuery library with a function whose signature looks like the following. This is for illustrative purposes only.
declare function my-func:ex-join($first as xs:string, $last as xs:string) as xs:string
{
fn:concat($first, '-', $last)
}
From XQuery, I can call this function with empty sequence as parameters, with no issues, i.e.
ex-join((), '1244')
The function will just return an empty sequence, but I don't get any errors. If I try to all this function from with in my XSL transform,as in:
<xsl:value-of select="my-func:ex-join(//node/value/text(), 'something')"/>
If the /node/value does not exist, and an empty sequence is passed in, I get the coercion error.
Does anyone have suggestions to work around the coercion problem, outside of checking the values in XSL prior to the select? These are auto-generated XSL templates, which would mean a lot of coded checks.
Thanks,
-tj
Attempts to invoke that function in XQuery would fail too. It is probably due to function mapping that you don't notice this though. Put the following at the top of your XQuery code:
declare option xdmp:mapping "false";
Next to this, you only need to change the signature of your function to accept empty-sequences. Replace as xs:string with as xs:string?:
declare function my-func:ex-join($first as xs:string?, $last as xs:string?) as xs:string
fn:concat will accept empty sequences as arguments, so no further changes required to make it work..
HTH!
When I define a spinner in ScalaJS and handle the spin value I am not able to get the new spin value in the event as I would have expected. According to the JQuery UI documentation the second parameter to the spin event is the ui object that contains a value attribute. So I defined a trait:
trait Number extends js.Object {
val value: Int = js.native
}
And then handle my spin event thus:
jQuery("#mySpinner").spinner(js.Dynamic.literal(spin = { (e: HTMLInputElement, ui: Number) =>
log("Change: " + ui.value)
}: js.ThisFunction1[HTMLInputElement, Number, Any]))
But the "value" attribute does not seem to be a member of the ui object as I get the exception below in my log statement. Can someone tell me what I am doing wrong?
uncaught exception: scala.scalajs.runtime.UndefinedBehaviorError: An
undefined behavior was detected: undefined is not an instance of
java.lang.Integer
You say e: HTMLInputElement but it should be e: Event
I suspect the problem is a combination of the previous comments. You are correct that, since you're using ThisFunction, the first element should be an Element of some sort. (Although, is it really an HTMLInputElement? That's a slightly unusual element type to put a spinner on.)
But that Element gets prepended to the function parameters, whereas you've got it replacing one.
In other words, you have
(e: HTMLInputElement, ui: Number)
but it needs to be
(elem: HTMLInputElement, e:Event, ui: Number)
in order to match the expected signature. So in practice, the system is trying to cast the value member of an Event, which of course doesn't exist, to Integer. It finds that value is undefined, tries to cast it to Integer, and boom.
I can't say I'm 100% certain (and IMO that ui parameter is just plain weird to begin with -- I'm a little suspicious of the jQueryUI documentation there), but that's my guess. Try fixing the signature of your call, and see if the error goes away...