Monday, August 26, 2013

Bleeding Edge May Be Incomplete


I need to stay away from the Dart mailing list because there is so much exciting stuff coming out that it is distracting me from what I need to do in order to finish up the next edition of Dart for Hipsters. That said…

Ooh, shiny! There is a new constant in the meta package: @proxy. The purpose is to indicate to tooling like dartanalyzer and the Dart Editor that a class is a proxy class. I believe that this comes primarily from js-interop proxy classes, which can wrap a whole bunch of JavaScript methods and properties in a fairly empty class.

The js-interop package make calling JavaScript from Dart very nice. But is seems to confuse dartanalyzer to no end. I make extensive use of js-interop in the ICE Code Editor to wrap classes from the JavaScript-based ACE code editor (sorry for the name similarity—I had not heard of ACE before I settled on ICE). The result of wrapping those classes is a barrage of dartanalyzer warnings:
➜  ice-code-editor git:(master) dartanalyzer lib/ice.dart
Analyzing lib/ice.dart...
[warning] There is no such getter 'ace' in 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 226, col 16)
[warning] The method 'setFontSize' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 295, col 40)
[warning] The method 'setTheme' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 296, col 38)
[warning] The method 'setPrintMarginColumn' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 297, col 44)
[warning] The method 'setDisplayIndentGuides' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 298, col 46)
[warning] The method 'setValue' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 300, col 40)
[warning] The method 'getValue' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 301, col 31)
[warning] The method 'focus' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 302, col 27)
[warning] The method 'getCursorPosition' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 307, col 33)
[warning] The method 'gotoLine' is not defined for the class 'Proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 309, col 13)
...
26 warnings found.
In dartanalyzer's defense, the proxy class really does not define these methods, so the warnings are correct. On the other hand, each of these methods is callable once the proxied JavaScript code is ready. Enter the @proxy annotation.

At least hopefully. If I add it to the ICE class in question:
@proxy
class Ace extends jsw.TypedProxy {
  // ...
}
I succeed only in adding yet another warning:
➜  ice-code-editor git:(master) dartanalyzer lib/ice.dart
Analyzing lib/ice.dart...
[warning] Undefined name 'proxy' (/home/chris/repos/ice-code-editor/lib/editor.dart, line 287, col 2)
...
27 warnings found.
Looks like I need an updated version of the meta package.

As awesome as Dart Pub is, one thing that is a pain is the need to peg libraries to specific versions in pubspec.yaml:
name: ice_code_editor
version: 0.0.10
description: Code Editor + Preview
# ...
dependencies:
  crypto: ">=0.6.17+2 <0.6.18"
  js: ">=0.0.24 <0.0.25"
  unittest: ">=0.6.15+3 <0.6.16"
  ctrl_alt_foo: ">=0.1.2 <0.1.3"
Everytime I want to update to the most recent versions, I have to change all of those to any:
name: ice_code_editor
# ...
dependencies:
  crypto: any
  js: any
  unittest: any
  ctrl_alt_foo: any
Then I have to pub update to get the generated pubspec.lock to use the correct versions:
➜  ice-code-editor git:(master) ✗ pub update
Resolving dependencies............
Downloading crypto 0.6.19 from hosted...
Dependencies updated!
Then, to get back to the specific versions, I pub lish the package even though I have no intention of actually publishing. Instead I publish to get the pre-publish warnings, which include the correct version ranges:
➜  ice-code-editor git:(master) ✗ pub lish
Publishing "ice_code_editor" 0.0.10:
...
Suggestions:
* Your dependency on "crypto" should have a version constraint. For example:

  dependencies:
    crypto: ">=0.6.19 <0.6.20"
...
After re-satisfying Pub by copying all listed dependencies back into pubspec.yaml, I try out dartanalyzer on the @proxy again, only to find that nothing has changed.

It turns out that I really, really need to stay away from the mailing list because this is a bleeding edge feature. So I install bleeding edge and do the pub dance again:
➜  ice-code-editor git:(master) ✗ dart --version                                        
Dart VM version: 0.1.2.0_r26680 (Mon Aug 26 17:57:26 2013) on "linux_x64"

➜  ice-code-editor git:(master) ✗ pub update
Resolving dependencies...........
Downloading crypto 0.6.21+3 from hosted...
Downloading stack_trace 0.6.21+3 from hosted...
Downloading meta 0.6.21+3 from hosted...
Downloading browser 0.6.21+3 from hosted...
Downloading path 0.6.21+3 from hosted...
Dependencies updated!
And find… I still get the same dartanalyzer warnings.

Ah well. My current solution that ignores the proxy warning in my Bash test runner will have to do:
results=$(dartanalyzer lib/ice.dart 2>&1)
non_js_results=$(
  echo "$results" | \
    grep -v "is not defined for the class 'Proxy'" | \
    grep -v "There is no such getter '.*' in 'Proxy'"
)
echo "$non_js_results"
non_js_count=$(echo "$non_js_results" | wc -l)
if [[ "$non_js_count" != "2" ]]
then
  exit 1
fi
if [[ "$non_js_results" == *"warnings found."* ]]
then
  echo "Ignoring js-interop warnings..."
fi
echo
...
I suppose that is about the same as the proposed @proxy so I will plan on switching over once it is fully baked.

The lesson learn tonight is that I must avoid the Dart mailing list. No wait, that's probably not a good idea. Bah, there is probably no lesson to be learned. Bleeding edge features sometimes are not quite ready, but are still fun to play with.


Day #855

1 comment:

  1. Chris,
    I really like your posts.
    Keep up the good work.
    Günter

    ReplyDelete