How do you opt out of null safety in Dart? - dart

As of Dart 2.12.0, null safety is enabled by default.
The "Enabling null safety" section on dart.dev states the following:
Set the SDK constraints to require a language version that has null safety support. For example, your pubspec.yaml file might have the following constraints:
environment:
sdk: ">=2.12.0-0 <3.0.0"
So now that it is enabled by default, how do we opt out of null safety and write code like before when our SDK constraint has >=2.12.0-0?
We might want to require a Dart version like this for a different language feature but not want to use NNBD.

There is no way to not use NNBD in a file that uses Dart >=2.12.0=0.
Thus, you only have two options to opt out of null safety:
Opting out file by file
Even if your minimum SDK constraint is >=2.12.0=0, you can opt-out single files using per-library language version selection.
At the very top of your file before any imports etc., you can specify the Dart version the whole file should use:
// #dart=2.11
import 'dart:math';
...
This way, that file will be able to opt-out of null safety by using Dart 2.11.
Lower the SDK constraint
If you lower Dart SDK constraint is below 2.12.0-0, you are by default opting out of null safety:
environment:
sdk: ">=2.11.0 <3.0.0"
Learn more by reading through the unsound null safety article on dart.dev.

Related

Using g_autoptr() together with G_DEFINE_AUTOPTR_CLEANUP_FUNC() when using older and newer GLib versions

There is something about using g_autoptr() together with G_DEFINE_AUTOPTR_CLEANUP_FUNC() when using different GLib versions which I don't understand (this affects also the other g_auto... variants and its G_DEFINEs).
The documentation says
"The way to clean up the type must have been defined using the macro
G_DEFINE_AUTOPTR_CLEANUP_FUNC()"
When using for example GLib 2.62 and using the G_DEFINE macro this results in errors like
/usr/include/glib-2.0/glib/gmacros.h:1032:49: error: redefinition of ‘glib_slistautoptr_cleanup_GtkTreePath’
1032 | #define _GLIB_AUTOPTR_SLIST_FUNC_NAME(TypeName) glib_slistautoptr_cleanup_##TypeName
Leaving out the G_DEFINE macro will solve the problem and the program works just fine.
However, on older GLib versions like 2.50 (which is for example still used by Debian 9), using the G_DEFINE macro will not result in an error message. But I can't see any changes reflected by the GLib documentation. I cannot determine when exactly the aforementioned change of behaviour has been introduced. How am I supposed to cope with this when I want to support all GLib versions from 2.50 on?
The issue is probably in Gtk, not GLib. g_autoptr() was supported for most things in Gtk+ 3.22 (the one in Debian 9) already: so you shouldn't have to call G_DEFINE_AUTOPTR_CLEANUP_FUNC() on Gtk types yourself. GtkTreePath however was still missing a call: this was added in 3.24, see https://gitlab.gnome.org/GNOME/gtk/-/commit/86dd1e37a70e9bae057a9a11332f7254cda242e8.
You'll probably have to do the macro call behind a version check if you want to use g_autoptr() with TreePath on Gtk < 3.24.

How can you tell if your Java program is running in a GraalVM AOT context?

I have a little Java program. I build a binary using Graal's native-image (i.e. GraalVM AOT aka SubstrateVM).
My program can be executed either with a Java runtime or from the native-image binary. What's the best way to tell which context I'm running in?
(This might be a bad practice in general but I believe it's inevitable/necessary in certain not-uncommon circumstances.)
Edit: There is now an API for that. See user7983712's answer.
The way it's done in the GraalVM is by capturing the com.oracle.graalvm.isaot system property: it is set to true while building AOT images. If you combine that with the fact that static initializers run during image generation, you can use
static final boolean IS_AOT = Boolean.getBoolean("com.oracle.graalvm.isaot")
This boolean will remain true when running the native image.
This is also useful to cut-off paths that you don't want in the final output: for example if you have some code that uses a feature that SVM doesn't support (e.g., dynamic class-loading) you can predicate it with !IS_AOT.
GraalVM now provides an API for checking the AOT context:
ImageInfo.inImageCode()
ImageInfo.inImageRuntimeCode()
ImageInfo.inImageBuildtimeCode()
ImageInfo.isExecutable()
ImageInfo.isSharedLibrary()
I'm leaning towards checking the presence/absence of some system properties. When I print out the system properties under Graal AOT I see:
{os.arch=x86_64, file.encoding=UTF-8, user.home=/Users/thom, path.separator=:, os.name=Mac OS X, user.dir=/Users/thom, line.separator=
, sun.jnu.encoding=UTF-8, file.separator=/, java.io.tmpdir=/var/folders/0x/rms5rjn526x33rm394xwmr8c0000gn/T/, user.name=thom}
As you may notice it's fairly short and is missing all the usual java.* ones such as java.class.path. I'll omit listing the lengthy Java version and instead link to another SO listing the usual Java System properties:
What is the full list of standard keys recognized by the Java System.getProperty() method?
So one way to do it would seem to be to check whether one or more of the java.* properties are absent.
AFAIK there are no plans to set these in SubstrateVM. But System properties are mutable so one could possibly choose to fake them.
But anyway here's a way to do it:
def isGraalAOT = System.properties.getProperty("java.class.path") == null

Sublime Text 3 - Set syntax for filetype in package/plugin

I am busy making a sublime text plugin/package that will ease development of lua scripts in my workplace.
We have several lua files with different extensions depending on their purpose. I want ST3 to give the proper lua syntax to these files.
I know you can set ST3 to remember syntax for a specific file extension and this is saved as a (in my case) Lua.sublime-settings file in AppData\Roaming\Sublime Text 3\Packages\User
However, if I put this file in my new plugin's folder, it's ignored.
Am I doing something wrong or is what I want not possible?
This doesn't work because syntax specific settings are only loaded from the package that defines the syntax and from the User package (so the user can customize them).
The following is a quote from the official documentation on settings:
Settings files are consulted in this order:
1. Packages/Default/Preferences.sublime-settings
2. Packages/Default/Preferences (<platform>).sublime-settings
3. Packages/User/Preferences.sublime-settings
4. <Project Settings>
5. Packages/<syntax>/<syntax>.sublime-settings
6. Packages/User/<syntax>.sublime-settings
7. <Buffer Specific Settings>
The only places where <syntax> is referenced is from the package itself and from the user package.
If I had to guess, I would say that this is because outside of the original package author that defined the syntax, all other settings would be considered user customizations, and those settings need to be in the User package (specifically in the root of it) to ensure that they're loaded last.
A simple (but undesirable) solution would be to document for the user that they have to take this step manually.
Another approach would be to add some plugin code that extends the settings when your plugin is loaded:
def plugin_loaded():
settings = sublime.load_settings("Lua.sublime-settings")
extensions = settings.get("extensions", [])
if "blarb" not in extensions:
extensions.append("blarb")
settings.set("extensions", extensions)
sublime.save_settings("Lua.sublime-settings")
If you go this route you may want to include an extra sentinel setting somewhere (in settings specific to your package or some such) that says if you did this or not instead of just forcing the setting in as the example above does.
In practice you would then check if you've set that sentinel or not instead of forcing the extension in, so that if the user decides to use some other syntax for your files you're not forcing them into the Lua syntax.
It's also possible to define your own syntax that just embeds the standard Lua syntax, which allows this to Just Work™ without having to write any code or have the user do anything:
%YAML 1.2
---
name: Blarb
scope: source.lua
file_extensions:
- blarb
contexts:
main:
- include: scope:source.lua
When you do this, the scope in the file will still be source.lua because that's what the scope in the syntax file says. and the status line will set the syntax name to Blarb. You could modify either of those to change the top level scope or displayed name, if desired.
An example would be to change the scope to source.blarb so that you could create key bindings/snippets that only apply to Lua files of your specific variant.
A potential downside/feature of this is that since the name of the syntax specific settings comes from the name of the file that provides the syntax, if the user has any Lua specific settings, they won't apply to your Blarb files by default.
Similarly anything that's specific to Lua by checking for a scope of source.lua won't work in Blarb files for same reasons, which may or may not be an issue.

Dart Angular 2 annotation how do they work?

I'm currently playing with the Dart version of Angular 2.
I have seen that the library is using a lot of Metadata as #Component for example.
I would like to know how are those directives working?
I went on http://www.darlang.org. They explain how to define an annotation but not how to use it to construct an object as it is done in angular.io.
Could someone explain how the magic is working?
In Dart annotations by itself don't do anything than exist beside the code element where they are added.
At runtime:
You can use dart:mirrors to query the imported libraries for elements like fields, functions, classes, parameters, ... for these annotations.
dart:mirrors is discouraged for browser applications. In this case you can use the reflectable package with quite similar capabilities.
See also:
https://www.dartlang.org/articles/reflection-with-mirrors/
https://api.dartlang.org/1.14.1/dart-mirrors/dart-mirrors-library.html
https://stackoverflow.com/search?q=%5Bdart-mirrors%5D+annotations
At buildtime
You can create a transformer and register it in pubspec.yaml to be run by pub serve and pub build.
In this case the Dart analyzer can be utilized to query the source files for annotations and, like Angular does, modify the source code in a build step to add/replace/remove arbitrary code.
For more details about transformers
- https://www.dartlang.org/tools/pub/assets-and-transformers.html
- https://www.dartlang.org/tools/pub/transformers/
- https://www.dartlang.org/tools/pub/transformers/examples/
- https://www.dartlang.org/tools/pub/transformers/aggregate.html
- https://pub.dartlang.org/packages/code_transformers

How to check for NS_AVAILABLE_IOS with const CGFloat

When a method can only be used on certain iOS versions, I usually check for its availability using respondsToSelector:.
With a const CGFloat declaration this is not possible.
The specific constant I'm trying to use is UIFontWeightBlack which is defined as:
UIKIT_EXTERN const CGFloat UIFontWeightBlack NS_AVAILABLE_IOS(8_2);
What is the best way to check if the iOS version my code is running in supports this constant?
Also if I want to support building my framework with older versions of the iOS SDK, what is the best way to check at compile time, if the used SDK offers this symbol?
I would currently do the check with
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_2
Is there a way to check for the symbol directly, without having to rely on / explicitly specify the iOS SDK version?
This is covered in the SDK Compatibility Guide.
Check the availability of an external (extern) constant or a notification name by explicitly comparing its address—and not the symbol’s bare name—to NULL or nil.
So your code would be:
if (&UIFontWeightBlack != NULL) {
// It is safe to use the constant
}
To answer the second part of your question, change your compile time check to the following:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80200 // 80200 is the value of __IPHONE_8_2
We want to fall back to use the value of the macro rather than the macro itself as the macro is not defined in older versions of the iOS SDK.
As you mentioned in a comment, this is covered in the Conditionally Compiling for Different SDKs section:
The following code excerpt demonstrates this. Notice the use of the
numerical value 1050 instead of the symbol __MAC_10_5 in the #if
comparison clause: If the code is loaded on an older system that does
not include the symbol definition, the comparison still works.

Resources