Hello, and welcome to the tutorial for the Dart Editor.
My name is Devon Carew.
I'm a software engineer at Google and a member of the
Dart project.
Dart is a new structured web programming language.
The Dart language is joined by libraries, a virtual machine,
tools, and a Dart to JavaScript compiler.
Today, I'll be taking you on a tour of the development
environment for Dart.
You can download a copy of the Editor at dartlang.org/editor.
This download also includes a copy of the Chromium browser
with Dart support built in, the Dart virtual machine, as
well as the class libraries and the Dart
to JavaScript compiler.
Dart, the language, and its libraries, the virtual
machine, and the tools are all open source.
Visit dartlang.org for more info on Dart, including code
samples, documentation, and the latest Dart news.
So now let's dig into the Editor.
First, when you open the Editor, it comes up with a
page of some sample applications.
We'll click on the clock sample app in
order to open it.
You can see that it's opened a clock project over here as
well some Dart files and the main clock Dart file in the
editing window.
In order to run this application,
click on the Run button.
And this will launch the application
and a copy of Dartium.
Dartium is a special build of the Chromium browser that
ships with the Editor and includes the
Dart virtual machine.
It supports Dart natively.
But we also have a good store for running your Dart
application on browsers that don't support Dart.
We have a Dart compiler, Dart to JavaScript, that compiles
your Dart application to JavaScript.
Let's see how that works.
If you choose the Tools, Generate JavaScript menu item,
it runs Dart to JS and produces a
JavaScript file as output.
You can see the output here.
And there's a new Dart to JS file in the files view.
We can open that file to look at the compiled JavaScript.
So now let's run this Dart application in a browser
without Dart support.
On the Run menu, choose the Manage Launches menu item.
There we'll create a new launch type, a JavaScript
launch, and select the HTML file we want to run,
Clock.html.
We'll name this launch and run it.
It'll invoke Dart to JavaScript, and generate
JavaScript, and launch a new browser.
So this is the Dart application running in Chrome
and just running JavaScript natively.
And an important point to note is that the same HTML file is
running both the Dart and JavaScript
version of the apps.
Let's see how that works.
Review the page source.
We can see that the HTML file is referencing the Dart
application.
So this will run just natively in a browser
with native Dart support.
And if you have a browser without that, it invokes a
Dart to JS script, which first checks to see if Dart is
available in the browser.
And if not, it rewrites your application Dart references to
append .js to it.
So that'll invoke the output of Dart to JS.
And your Dart application will just run in that browser.
So now let's open a more complicated example.
We'll be working with this example for the
rest of this tutorial.
The File Open menu item.
We'll be opening existing applications, and work with
them in the Editor.
I'm going to choose one I wrote for the
purposes of this tutorial.
And it's open, and you can see it in the files view.
And open the main file for it.
The app consists of a CSS file, HTML, and a Dart file.
Let's run it very quickly, and see what it does.
OK, so it's a visualization of the solar system, with the sun
and the moon and a couple of asteroids
distributed in there.
One of the things the Editor is good at is navigating and
visualizing your application.
Because Dart is a structured programming language, we have
a very good semantic knowledge of your source base.
First off, let's open the outline view.
This is going to show you the types and methods in your file
you're editing.
So we see that we have a planetary body class.
It has an add planet method, a draw children and a draw self
method, and a solar system class, which knows how to draw
itself and draws planets.
And we have two top level functions, a main, which is
your entry point, and a show FPS method.
Another useful thing we support is hyperlinking within
your application.
So you can jump to the definition of classes and
methods you use.
I'll jump to this constructor definition and back and this
method definition.
And you're not just limited to hyperlinking within your
application.
You can navigate into the core libraries, as well.
Let's see an example of that.
So I want to see how this log method is implemented.
I can hyperlink into it.
And I see the actual definition of it.
And that brings me to another point, that the full SDK
sources are available in the Editor.
So you can see all the libraries in the SDK, and you
can explore them and look at their implementations.
Another feature we have is the callers view.
This view let's you see all references to a field or all
callers of a method.
This is something that is possible because we have a
full semantic knowledge of the source base.
Let's see this in action.
So if I select this window field, right click on it, and
choose Open Callers, we'll see that we have lots of
references to it.
And we can dive into those specific references.
This is in our own source base.
We can look and see in the actual SDK sources.
It references the window field.
And the caller view supports finding
reference methods as well.
Another useful way to navigate in the Editor is using our
search box.
So let's say that I know I want to display a browser
alert box in my application.
I might not know exactly what class it defined on or the
method is called, but I can guess it would be something
like alert.
So let's type that in.
And I can select Occurrences of Alert, and it searches
through the user code as well as the SDK code.
I see I have several matches, and I'm going to explore this
one in the HTML library.
And I find a likely candidate.
It's an alert method, and it takes a string as a parameter.
Using the outline view, I can see that it's defined in a
class called dom window impl.
And if I look at that implementation, I can see that
it implements the window interface.
So from that I can reasonably infer that the window object
is going to have an alert method on it.
Let's type that in and see what happens.
I'm going to save and run my application.
And we get an alert box.
So our search isn't just a textual search.
It's a semantic search, as well.
If I type in planetary body into the search box, I could
see the type that I've defined in my application and jump to
the definition.
We also have support for discovering
documentation and user code.
Dart supports the notion of literate programming in the
form of Dart doc comments.
Here's an example of one, and here's an example of another.
A Dart doc syntax is a form of markdown and is basically a
very simple, readable form of inline documentation.
We parse it in the Editor, and whenever you hover over an
element that's been documented, you get a tool tip
with a Dart doc inline.
This is useful for SDK code, as well.
Let's see that.
So maybe I've forgotten the exact return type of random,
but I can hover over it and see that it's specified a
return value between zero and one.
Finally, all of our documentation for our core
libraries is available online.
You can navigate to them from the help API
Reference menu item.
The Editor has full semantic knowledge of the user's code,
and it maintains this knowledge by continually
analyzing the source code.
There's no explicit compile step.
As soon as the user pauses typing or saves a file, we
re-analyze the modified file.
Let's see an example of this.
In the start method, we'll change the call to sun add
planet to sun add planetoid.
If I save, the Editor shows a warning, saying it doesn't
know anything about the sun planetoid method.
Now, this particular problem is a warning and not an error.
The Editor thinks that it knows what the type of object
is and what methods are available on it.
But the final arbitrator of this bit of code
will be the run time.
If this object at run time does not support the add
planetoid method, the code will run just fine.
If we run this code, we see that Dartium threw an
exception and that it was a no such method exception.
And it really doesn't think that this method exists.
So let's remove that method.
And instead, we'll modify this planetary body constructor.
If we change the name of it and save, again, the Editor
doesn't think that constructor exists.
But now it's an error, not a warning.
And that's because sometimes in our type system, we really
do need to know the type of an object and especially when
we're creating it.
One of the strengths of Dart is that it's a structured
programming language.
If you make use of the optional types in your
application, the development tools can form a good semantic
picture of your code base.
This allows for sophisticated features like code
refactorings.
The ability to easily and safely refactor
code is a huge benefit.
It allows you to work on large code bases in bigger teams. It
allows you to change and modify the code over time in
order to keep that code healthy.
The Dart Editor supports several refactorings.
I'm going to show off our renamer refactor now.
Let's say I decide that this add planet method really
should be called add planetoid.
I can select it and choose Edit, Rename.
Then type in planetoid and hit Return.
The method name is changed at that call site and all other
call sites.
And if I hyperlink to the definition, you can see it's
changed there as well.
I can hyperlink back.
And our refactorings also have full undo and redo support.
Another refactoring we have is extracting expression into a
local variable.
So let's go to the calculate speed method.
And if we look at it, we see we have several constants that
we could reasonably extract into a local variable.
We go to the Edit menu, choose Extract Local Variable, add a
name for it, hit Return, and we see it's done the
refactoring.
And it's actually also inferred that the type of the
local variable search should be a double.
So now let's play around with one of the hallmarks of a
modern development environment, code completion.
We'll go to the Start method, and extract out a local
variable before we create Mars.
And now I want to add a few satellites to Mars, but I'm
not really familiar with the planetary body class or which
methods it supports.
If I just type it in and invoke code completion, it'll
come up with all the fields and methods available on the
planetary body class, including one called add
planet, which looks like a likely candidate.
Now we want to create a new planet.
I type in the constructor.
I'll let code completion finish the rest of the typing
for me, including filling in all the variable names.
Let's finish this up.
Save, and run the application.
So you can see that Mars now has a new moon around it.
So code completion is also great for
exploring APIs in the SDK.
If I navigate to the draw background method, I can see
that we're drawing into a context object.
If I want to see what other drawing operations it
supports, I can invoke code completion and browse the
available fields and methods.
So I see that I have some shadowing operations
available, BZA curves, and general drawing operations.
In order to allow you to use untyped code and still get the
benefits of our Editor features, we've included a
type inference engine.
It'll make a best effort to infer what the type of your
var variable is and treat it accordingly.
You'll get code completion as well as verification of fields
and method calls, all without having to explicitly identify
the type of your variable.
Let's see this in action.
I'm going to go to the draw children method.
If you look in here, you can see that we have an untyped
var planet variable.
Because it's in a for loop, iterating over a list of
planetary body objects, we can infer that planet itself is a
planetary body.
If we activate code completion for that variable, we can see
that it does in fact have the appropriate fields and methods
for a planetary body class.
And if we add a var foo declaration, and try and code
complete it, we can see that we get all the valid
completions for this string class.
So the Editor has correctly inferred that this untyped var
foo is, in fact, a string.
One of the hallmarks of a modern development environment
is debugging, and the Editor brings full support for
source-level debugging to Dart.
We allow you to debug your applications running in
Dartium, and support the usual debugging suspects like break
points, variable inspection, and stepping.
And one nice feature is that, because of the way the virtual
machine is implemented, turning on debugging by and
large does not affect your application's execution speed.
So let's take a look at debugging in action.
We'll set a break point in the start method and run the
application.
This will launch Dartium and connect the debugger.
And now you see we've hit the break point.
We can see the call stack and the frames on the stack.
You can navigate around and inspect local variables.
Simple object types like ints and strings, we show the
values of, and more complicated objects, we call
the toString method of.
You can see that the Earth object just says instance of
planetary body.
This is the default toString result, but let's change that
to something that's a little bit more descriptive.
We'll navigate to the planetary body class and add a
toString method.
If we save and re-run the application, we can see that
we've hit the same break point, but the value for Earth
that's displayed is now the new toString method.
And notice that we were able to get the result of the code
change without having to restart Dartium.
Another way to inspect local variables is by
hovering over them.
So we're can hover over the Earth variable.
And it calls the toString method on it.
And we can hover over the this variable.
And it'll call the default toString of the
solar system class.
What's nice about this is that you can see the values of the
variables without having to lose context or try to locate
them in the variables view.
Now let's show some stepping.
Let's set a break point in the draw
method and resume execution.
We hit the break point, and we can see the values of the
local variables.
But more importantly, we can also trace the execution of
the application.
So let's step into the draw background call and step over
a few times and step out.
If we step into the draw planets call, we can see
something interesting.
If we step in again, you'd expect to step into the sun
draw method.
But we actually step into the width getter.
This is because it looks like a property access.
It's really an invocation of a getter.
The debugger also supports resuming execution and
terminating the process.
While Dart's primary focus is on the web, we also support
command-line applications.
In order to show this off, we'll open one of the examples
that ships with the Editor.
If you go to the Tools, Welcome Page menu item, you
can see that we have a time server example.
This is a simple HTTP server that responds with the current
date and time.
We can click on it in order to open the application, and then
click on the Run button to run it.
For command-line applications, just like in Dartium launches,
the process app shows up in the console view at the bottom
of the Editor.
From this view, you can clear the process output and can
choose to terminate the application.
Let's run it again, and verify that the web server is, in
fact, running.
So let's copy this URL, paste it into Chrome.
And we see that we get a response back
from the web server.
And if we go back to the console output, we can see
that we've got several requests for resources.
Diving into the source, we can see that the application
imports the Dart IO library.
This is the main library for command line applications.
It supports file and networking operations, process
management functions, and other operations useful in a
command line, non-browser environment.
Again, in order to find out more info about this library,
you can hyperlink into it and explore the implementation, or
get more documentation online using the API reference.
Thank you for watching this tour of the Dart Editor.
To get more information about Dart, please visit
dartlang.org.
And to download the Editor, visit dartlang.org/editor.
Thanks again.