Does dart allows users to write platform specific implementation? - dart

If not - are there are any plans to make it so?
I know that dart itself has different backends that might have different implementation. I was curious if users can do the same, e.g. have a function that delegates to one #patch for js runtime and to another #patch in case of dart vm.

If you're creating a package, you can export different implementations for different platforms, see here: https://dart.dev/guides/libraries/create-library-packages#conditionally-importing-and-exporting-library-files

The way to make platform specific code (or rather platform library specific code) is to use conditional imports.
The syntax is:
import "helper_default.dart"
if (dart.library.js) "helper_js.dart"
if (dart.library.io) "helper_io.dart";
This import statement will import one of three libraries. If the dart:js library is available on the platform you are compiling for, you will import helper_js.dart. If not, and dart:io is available, then you will import helper_io.dart. If that's also not there, you will import helper_default.dart.
The trick is then to have the same library API implemented in all three libraries, but based only on the available platform library.
The helper_js.dart library can implement something using dart:js and helper_io.dart can import dart:io. The default library will likely not be able to do anything useful, so it might just throw an UnsupportedError if you try to use it.
The code in the importing library must be valid for all three imports, which is why they must have "the same" API. That might include declaring a class, but you'd usually define the interface of that class in a non-platform dependent library that the three implementations can share, to ensure that they actually have the same interface.
Example:
library mypkg.shared_types;
import "helper_default.dart"
if (dart.library.js) "helper_js.dart"
if (dart.library.io) "helper_io.dart"
as helper;
class SharedClass {
factory SharedClass(int something) = helper.SharedClassImpl;
int get value;
}
and
library mypkg.helper_io;
import "dart:io";
import "shared_types.dart";
class SharedClassImpl implements SharedClass {
int _id;
SharedClassImpl(this._id);
int get value { // Something depending on dart:io.
var bytes = File("pathToSomething-$id").readAsBytesSync();
return bytes[0];
}
}

Related

dart "part of" can't used twice in a file

I have a class named _AppColors. it contains all colors used in the application. I want to force developers to read colors from Theme that's why I made this class private. now I want to access this class from two files. but it can be only part of one file. how can I handle this?
app_colors.dart:
part of 'color_extention.dart';
class _AppColors {
...
app_theme.dart
import 'package:flutter/material.dart';
part 'app_colors.dart';
extension MultiThemeColorExtension on ThemeData {
...
color_extention.dart
import 'package:flutter/material.dart';
part 'app_colors.dart';
const TextTheme _textThemeLight = TextTheme(
...
but I have to add part of 'color_extention.dart'; in app_colors.dart which I can't. any solution?
Private symbols are private to the library. Normally a Dart library is a single .dart file, but part is used to specify that a library comprise multiple .dart files (and conversely, part of is used to specify that a .dart file is part of the specified library).
It doesn't make sense for a Dart file to be part of multiple libraries. If you want to share a private class with multiple .dart files, your typical options are:
Make all of those .dart files part of the same library.
Make your class public instead but discourage using them. Packages typically do this by placing internal implementation files in lib/src/ and exporting only the symbols intended for public consumption.

How to access private (underscore) identifiers in the same library but in a different file

According to dart.dev, "If an identifier starts with an underscore (_), it’s private to its library.". This should mean that separate files using the same library directive should be able to see private identifiers in the other ones, right? For instance:
other.dart:
library mylib;
const _foo = 42;
main.dart:
library mylib;
import 'other.dart';
void main() {
print(_foo); // Error: Getter not found: '_foo'.
}
What am I doing or understanding wrong here?
Although this is not a duplicate of Dart and underscores as suggested, that question itself (rather than one of its answers) did include a clue for answering this one. You need to use the part/part of directives to accomplish what I was trying to do. dart.dev mentions them but seems so determined to discourage their use that it refuses to even begin to explain how they work, so see dart import and part of directives in same file for a brief explanation.

What is the difference between these two packages importing ways in Dart language?

There are two ways to import packages in Dart programming language, I need to know what is the difference between them both, please?
Also when to use the first way and when to use the second way?
First way:
import 'dart:io';
Second way
import 'dart:io' as io;
as io specifies a prefix.
Without you can use members dart:io exports like
var f = File();
with prefix it would be
var f = io.File();
This is useful to disambiguate imports if names collide with declarations in your current library or another imported library.
Packages like path assume that they are imported with a prefix, because it exports many top-level functions with common names that without a prefix would clutter the scope.

Why Is the "library" line needed for Dart?

For a library file (say foo.dart), you start it with a line like this:
library my_foo_lib;
Why is it needed? The import is based on file name (foo.dart), not library string (my_foo_lib):
import 'package:foo.dart';
Having to declare library seems redundant and error-prone. Is there a good reason behind it?
You can omit the library statement then it is an implicitly named library with an empty string as name but when you import a library you need to name it explicitly otherwise you get an error that you have several libraries with the same name.
Identifiers starting with an _ (underline) are private. Privacy in Dart is per library.
The part of references the library name.
When you use reflection to look up classes or functions you include the library name. This way you can differentiate classes with the same name in different libraries.
Dart Programming Language Specification (17 Libraries and Scripts) also says
"The name may be relevant for further language evolution."

Warning that 'imported libraries have the same name when they DO NOT"

I have the following import statements in a class
import 'package:dart_web_toolkit/ui.dart';
import '../../util/flex_table_builder.dart' as ftBldr;
import '../factors_list_view.dart';
class MediatingFactorsView extends Composite
{
//...
}
However, the last import statment is flagged with a warning:
The different imported libraries 'flex_table_builder.dart' and 'factors_list_view.dart' should not have the same name
The names are quite different and I see this being repeated throughout my code after I updated to the latest Dart Editor. Is this a bug?
Make sure that you are assigning library names to each file. The first line of the file should be:
library foo;
You should use different names for each library that you use. The library name is specified by the library directive, but anonymous libraries are treated as having the same name, which is where the warning comes from.
It is a warning in the Dart specification to import two libraries with the same name.
You can read more about how to use libraries here in the language tour.
You could follow the Package layout conventions.
For the error :
The different imported libraries onset_view.dart and duration_view.dart should not have the same name
you should define distinct library names in each imported dart file.
One additionnal note, you should use import 'package:epimss/shared.dart'; instead of import 'packages/epimss/shared.dart'; and import 'site_view.dart'; instead of import './site_view.dart';
The warnings correctly indicate there is a problem.
The correct solution depends on if the Dart files are conceptually separate from each other or are related.
Different libraries
If they are conceptually separate, then they should be defined as belong to different libraries with different library names.
The import command is used to reference a compilation unit from a different library, not a compilation unit that belongs to the same library. It expects every library to have a unique library name.
If a Dart file is treated as a library (i.e. is the subject of an import statement) and is not explicitly named then its implicit name is the empty string. In this case, both files are treated as libraries, and it is complaining about there being two libraries with the same name (of an empty string).
For this to work as separate libraries, given them different names:
Top file:
import 'foo.dart';
import 'bar.dart';
foo.dart:
library foo;
bar.dart:
library bar;
Part of the same library
But if they related they should not be referenced as libraries. That is, do not use the import command. Use the part command, which treats the Dart file as compilation unit that belongs to the same library.
Top file:
library baz;
part 'foo.dart';
part 'bar.dart';
foo.dart:
part of baz;
bar.dart:
part of baz;
Only the top library file can contain the part statements. You do not need (and cannot have) part statements inside the other files, even if they reference definitions from each other. If there are multiple files, just list them all in the top library file (in any order).
Although the implicit name for a library is the empty string, there is no way to use that when there are multiple parts involved: so even if these files are never going to be imported as a library, you will still need to explicitly assign it a library name.
Always remember: import and part statements are very different from the #include macro in the C preprocessor.

Resources