Dart library visibility - dart

My Dart app has the following structure:
myapp/
pubspec.yaml
pubspec.lock
asset/
...
web/
logging/
Logger.dart
LogLevel.dart
...other packages
Where the 2 shown Dart files are:
LogLevel.dart:
library logging;
class LogLevel {
static const TRACE = const LogLevel._(0);
static const INFO = const LogLevel._(1);
static const ERROR = const LogLevel._(2);
static get values => [TRACE, INFO, ERROR];
final int value;
const LogLevel._(this.value);
}
Logger.dart:
library logging; // <== compiler error!?!
import "package:logging/LogLevel.dart";
class Logger {
// ...
}
I figured since I put the two classes into a logging library/package together, that they would be visible to one another. But that's not the case! Instead on the import statement I get the following compiler error:
Target of URI does not exist: 'package:logging/LogLevel.dart'
What's going on here? How should I be packaging/library-ing my types differently so that they'll be visible to one another?

You can import them through their relative path without referring to the package:
import 'LogLevel.dart';
If you do want to import them as packages, they need to be under the lib folder.

Related

Dart Can't get logging statements to compile

I'm trying to learn how to implement logging using the examples/tutorial in:
http://blog.dartwatch.com/2013/05/campaign-to-use-real-logging-instead-of.html#comment-form
But having imported the libraries this line in main will not compile because the class 'PrintHandler' is not recognized and Google has not been a help in this case. My server application consists of a main and three classes. I'm new at Dart. Below I've extracted the logging code that I added.
In what library is 'PrintHandler'? Is this a class I need to write?
library server;
import 'package:logging_handlers/logging_handlers_shared.dart';
import 'package:logging/logging.dart';
final _serverLogger = new Logger("server"); // top level logger
void main() {
Logger.root.onRecord.listen(new PrintHandler()); // default PrintHandler
_serverLogger.fine("Server created");
}
class A {
}
class B {
}
class C {
}
It looks like the class was changed to LogPrintHandler but the tutorial and documentation were not updated.

Export two library which have same class name

I met an error when exporting two libraries. And these libraries have exactly same class name.
File: A.dart
library chrome.A;
class MyClass {
...
}
File: B.dart
library chrome.B;
class MyClass {
..
}
File: C.dart
library chrome_app;
export 'A.dart';
export 'B.dart'; // HERE!! error message for the element 'MyClass' which is defined in the libraries 'A.dart' and 'B.dart'
Is this the intended result?
I think A.dart and B.dart has their own namespace so that there should be no error.
A library name isn't a namespace. Dart doesn't have namespaces.
What you can do in Dart is to specify a prefix for an import.
You have to import those libraries separately if you want to use them in the same library instead of just one import with import 'C.dart;'
import 'A.dart' as a;
import 'B.dart' as b;
var m = a.MyClass();
var n = b.MyClass();
If you just want to avoid the conflict and don't need both classes exported you can.
library chrome_app;
export 'A.dart';
export 'B.dart' hide MyClass;
// or
export 'B.dart' show MyOtherClass, AnotherOne; // define explicitly which classes to export and omit MyClass

Dart 2 libraries in one lib folder causing type 'X' is not a subtype of type 'X'

I have a following problem:
In my application, I have web and lib folders.
Lib folder is supposed to contain utility libraries.
Example:
lib/my_lib.dart
library my_lib;
part 'src/person.dart';
lib/my_lib1.dart
library my_lib1;
import 'my_lib.dart';
part 'src/other.dart';
In my_lib1, I want to use classes defined in my_lib
the classes are as follows:
lib/src/person.dart
part of my_lib;
class Person {
}
lib/src/other.dart
part of my_lib1;
class Other {
Person p;
Other(this.p) {
print(p);
}
}
Now, in web/testpackage.dart
import 'package:TestPackage/my_lib.dart';
import 'package:TestPackage/my_lib1.dart';
void main() {
Person p = new Person();
Other o = new Other(p);
}
Fails with:
Exception: type 'Person' is not a subtype of type 'Person' of 'p'.
Other.Other (package:testpackage/src/other.dart:7:14)
How should I structure my project to prevent that?
My libraries are local to the app, and I don't really want to develop them separately for my toy project.
Problem in that the your library my_lib is a publiclibrary and anyone (and you, of course) can use it elsewhere outside of lib directory.
In this case it must be imported (becuase it's a public library) always as the package library.
To solve this this problem you must change your source code.
From this lib/my_lib1.dart
library my_lib1;
import 'my_lib.dart';
part 'src/other.dart';
To this lib/my_lib1.dart
library my_lib1;
import 'package:TestPackage/my_lib.dart';
part 'src/other.dart';

Internal Error:... ambiguous reference: 'DataGrid' is defined in library web/DataGrid.dart and also in web/out/DataGrid.dart

I created a bare-bones datagrid using web-ui for testing and had it working just fine. Then I decided to try to declare it as a component. I changed around the library references and now it is giving me the above error when I try to run the application. You can see my file structure below. The reason I am getting the "ambiguous reference" message when I try to run it is that when I went into the auto-generated DataGrid.dart file in the out directory, it had the following declaration
import 'DataGrid.dart';
...
import '../DataGrid.dart';
I am confused as to why the generated code imports them both. One thing that I considered is that it could be because the DataGridPage.html file instantiates my DataGrid component and my DataGridPage.dart file imports DataGrid.dart so that it can have references to DataGridColumn (it needs to set the columns for the DataGrid). In DataGridPage.dart, I also attach to certain DataGrid events such as SortColumnChanged and SelectionChanged so I need to request a copy of my DataGrid instance in DataGridPage.dart (I don't think there is a way to attach to events from the web component instantiation in DataGridPage.html).
Any ideas about what I am doing wrong?
Here is my file structure:
DataGrid.dart
--------------------------------------------
library datagrid;
...
part 'DataGridColumn.dart';
part 'DataGridRow.dart';
class DataGrid extends WebComponent{...}
DataGridRow.dart
--------------------------------------------
part of datagrid;
class DataGridRow {...}
DataGridColumn.dart
--------------------------------------------
part of datagrid;
class DataGridColumn {...}
DataGrid.html
--------------------------------------------
[contains the component declaration UI]
DataGridPage.html
-----------------------------------------
...
<div is="s-datagrid" id="myDataGrid" ItemsSource="{{app.Assets}}" Columns="{{app.Columns}}"></div>
...
DataGridPage.dart
--------------------------------------------
import 'DataGrid.dart';
import 'Asset.dart';
void main() {
}
DataGridApp _app;
DataGridApp get app {
if (_app == null) {
_app = new DataGridApp();
}
return _app;
}
class DataGridApp{
//provides ItemsSource and DataGridColumn data
}
jmesserly has answered this on the github site. He said that you need to remove the component import in your main dart file. So in my example I would remove the import 'DataGrid.dart' statement from the DataGridPage.dart. The IDE will give you a warning but you can ignore it because it will actually be run from the out folder.
GitHub Web-UI Issue 342

Duplicate top-level declaration 'METHOD main' in dart

I'm new to dart, and trying to use dart to write a hello world and a unit test, but I get the error:
duplicate top-level declaration 'METHOD main' at ../app.dart::5:6
My project dir is test-dart, and it has 3 files.
test-dart/models.dart
class User {
hello(String name) {
print("Hello, ${name}");
}
}
test-dart/app.dart
#library("app");
#source("./models.dart");
void main() {
new User().hello("app");
}
test-dart/test/test.dart
#library("test");
#import("../app.dart");
void main() {
print("hello, test");
}
Now there is an error in "test.dart" on void main(), the error message is:
duplicate top-level declaration 'METHOD main' at ../app.dart::5:6
The two main() methods are in different libraries, why they are still duplicated? How to fix it?
If you import a library like this #import('../app.dart), then all names from app.dart become visible in the importing code (all public names, actually -- those that don't start with a _). So in your test.dart library, you now have two main functions visible. That is obviously a collision. There are two ways to solve it (that I know of).
First: import the library with a prefix, like this: #import('../app.dart', prefix: 'app'). Then, all public names from app.dart are still visible, but only with an app prefix, so the main function from app.dart is only accessible by app.main. No collision here, but you have to use a prefix everytime.
Second: using a show combinator, like this: #import('../app.dart', show: ['a', 'b']). Then, it is no longer true that all names from app.dart are visible, only those explicitly named (a and b here). I'm not sure if this is already implemented, though.
Maybe in the future, we will get something opposite to the show combinator, so that you could do #import('../app.dart', hide: ['main']). That would be the best solution for your problem, but it isn't in the current language (as specified by 0.09).
You are importing app.dart without a prefix which means that the symbols of the importing and imported library can collide if there are duplicates such as in your example.
To resolve these collisions the library import allows you to prefix imports with an identifier. Your example should work if you change test.dart as follows:
#library("test");
#import("../app.dart", prefix: "app");
void main() {
print("hello, test");
app.main();
new app.User().hello("main");
}
Notice how the classes and top-level functions in the app.dart library are now accessed using the "app" prefix and thus do not collide with the names in test.dart.

Resources