Version 1.2.0-dev.5.2

svn merge -c 32606 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 32624 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 32632 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 32639 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 32643 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

R=kasperl@google.com

Review URL: https://codereview.chromium.org//163133002

git-svn-id: http://dart.googlecode.com/svn/trunk@32644 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/docgen/bin/docgen.dart b/pkg/docgen/bin/docgen.dart
index 21ba38a..f89162a 100644
--- a/pkg/docgen/bin/docgen.dart
+++ b/pkg/docgen/bin/docgen.dart
@@ -35,6 +35,12 @@
   var scriptDir = path.dirname(Platform.script.toFilePath());
   var introduction = includeSdk ? '' : options['introduction'];
 
+  var pubScript = options['sdk'] != null ? 
+      path.join(options['sdk'], 'bin', 'pub') : 'pub';
+
+  var dartBinary = options['sdk'] != null ? 
+      path.join(options['sdk'], 'bin', 'dart') : 'dart';
+
   docgen(_files,
       packageRoot: options['package-root'],
       outputToYaml: !options['json'],
@@ -46,7 +52,10 @@
       out: options['out'],
       excludeLibraries: excludedLibraries,
       includeDependentPackages: options['include-dependent-packages'],
+      compile: options['compile'],
       serve: options['serve'],
+      dartBinary: dartBinary,
+      pubScript: pubScript,
       noDocs: options['no-docs'],
       startPage: startPage);
 }
@@ -116,9 +125,13 @@
   parser.addFlag('append',
       help: 'Append to the docs folder, library_list.json and index.txt',
       defaultsTo: false, negatable: false);
-  parser.addFlag('serve', help: 'Clone the documentation viewer repo locally '
-      '(if not already present) and start a simple server', defaultsTo: false,
+  parser.addFlag('compile', help: 'Clone the documentation viewer repo locally '
+      '(if not already present) and compile with dart2js', defaultsTo: false,
       negatable: false);
+  parser.addFlag('serve', help: 'Clone the documentation viewer repo locally '
+      '(if not already present), compile with dart2js, '
+      'and start a simple server',
+      defaultsTo: false, negatable: false);
   parser.addFlag('no-docs', help: 'Do not generate any new documentation',
       defaultsTo: false, negatable: false);
   parser.addOption('introduction',
@@ -136,6 +149,9 @@
         'in the directory with its pubspec. Includes documentation for all '
         'of its dependent packages.',
       defaultsTo: true, negatable: true);
+  parser.addOption('sdk',
+      help: 'SDK directory',
+      defaultsTo: null);
   parser.addOption('start-page',
       help: 'By default the viewer will start at the SDK introduction page.'
         'To start at some other page, e.g. for a package, provide the name '
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index d316780..541a8ac 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -106,6 +106,8 @@
 /// also be documented.
 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
 /// This option is useful when only the SDK libraries are needed.
+/// If [compile] is `true`, then after generating the documents, compile the
+/// viewer with dart2js.
 /// If [serve] is `true`, then after generating the documents we fire up a
 /// simple server to view the documentation.
 ///
@@ -114,8 +116,9 @@
     bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
     bool parseSdk: false, bool append: false, String introFileName: '',
     out: _DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries : const [],
-    bool includeDependentPackages: false, bool serve: false,
-    bool noDocs: false, String startPage}) {
+    bool includeDependentPackages: false, bool compile: false, bool serve: false,
+    bool noDocs: false, String startPage, 
+    String pubScript, String dartBinary}) {
   var result;
   if (!noDocs) {
     _Viewer.ensureMovedViewerCode();
@@ -125,21 +128,29 @@
         introFileName: introFileName, out: out,
         excludeLibraries: excludeLibraries,
         includeDependentPackages: includeDependentPackages,
-        startPage: startPage);
+        startPage: startPage, pubScript: pubScript, dartBinary: dartBinary);
     _Viewer.addBackViewerCode();
-    if (serve) {
+    if (compile || serve) {
       result.then((success) {
         if (success) {
-          _Viewer._cloneAndServe();
+          _createViewer(serve);
         }
       });
-    }
-  } else if (serve) {
-    _Viewer._cloneAndServe();
+    } 
+  } else if (compile || serve) {
+    _createViewer(serve);
   }
   return result;
 }
 
+void _createViewer(bool serve) {
+  _Viewer._clone();
+  _Viewer._compile();
+  if (serve) {
+     _Viewer._runServer();
+   }
+} 
+
 /// Analyzes set of libraries by getting a mirror system and triggers the
 /// documentation of the libraries.
 Future<MirrorSystem> getMirrorSystem(List<Uri> libraries,
@@ -247,6 +258,12 @@
   /// --exclude-lib.
   static List<String> _excluded;
 
+  /// The path of the pub script.
+  static String _pubScript;
+
+  /// The path of Dart binary.
+  static String _dartBinary;
+
   /// Logger for printing out progress of documentation generation.
   static Logger logger = new Logger('Docgen');
 
@@ -265,9 +282,13 @@
        bool includeSdk: false, bool parseSdk: false, bool append: false,
        String introFileName: '', out: _DEFAULT_OUTPUT_DIRECTORY,
        List<String> excludeLibraries : const [],
-       bool includeDependentPackages: false, String startPage}) {
+       bool includeDependentPackages: false, String startPage,
+       String dartBinary, String pubScript}) {
     _excluded = excludeLibraries;
     _includePrivate = includePrivate;
+    _pubScript = pubScript;
+    _dartBinary = dartBinary;
+
     logger.onRecord.listen((record) => print(record.message));
 
     _ensureOutputDirectory(out, append);
@@ -595,7 +616,7 @@
   static List<String> _allDependentPackageDirs(String packageDirectory) {
     var packageName = Library.packageNameFor(packageDirectory);
     if (packageName == '') return [];
-    var dependentsJson = Process.runSync('pub', ['list-package-dirs'],
+    var dependentsJson = Process.runSync(_pubScript, ['list-package-dirs'],
         workingDirectory: packageDirectory, runInShell: true);
     if (dependentsJson.exitCode != 0) {
       print(dependentsJson.stderr);
@@ -639,6 +660,7 @@
       'dartdoc-viewer');
   static Directory _dartdocViewerDir = new Directory(_dartdocViewerString);
   static Directory _topLevelTempDir;
+  static Directory _webDocsDir;
   static bool movedViewerCode = false;
 
   /// If our dartdoc-viewer code is already checked out, move it to a temporary
@@ -660,7 +682,7 @@
   }
 
   /// Serve up our generated documentation for viewing in a browser.
-  static void _cloneAndServe() {
+  static void _clone() {
     // If the viewer code is already there, then don't clone again.
     if (_dartdocViewerDir.existsSync()) {
       _moveDirectoryAndServe();
@@ -671,7 +693,22 @@
           runInShell: true);
 
       if (processResult.exitCode == 0) {
-        _moveDirectoryAndServe();
+        /// Move the generated json/yaml docs directory to the dartdoc-viewer
+        /// directory, to run as a webpage.
+        var processResult = Process.runSync(_Generator._pubScript,
+            ['upgrade'], runInShell: true, 
+            workingDirectory: path.join(_dartdocViewerDir.path, 'client'));
+        print('process output: ${processResult.stdout}');
+        print('process stderr: ${processResult.stderr}');
+
+        var dir = new Directory(_Generator._outputDirectory == null? 'docs' :
+            _Generator._outputDirectory);
+        _webDocsDir = new Directory(path.join(_dartdocViewerDir.path, 'client',
+            'web', 'docs'));
+        if (dir.existsSync()) {
+          // Move the docs folder to dartdoc-viewer/client/web/docs
+          dir.renameSync(_webDocsDir.path);
+        }
       } else {
         print('Error cloning git repository:');
         print('process output: ${processResult.stdout}');
@@ -680,32 +717,17 @@
     }
   }
 
-  /// Move the generated json/yaml docs directory to the dartdoc-viewer
-  /// directory, to run as a webpage.
-  static void _moveDirectoryAndServe() {
-    var processResult = Process.runSync('pub', ['update'], runInShell: true,
-        workingDirectory: path.join(_dartdocViewerDir.path, 'client'));
-    print('process output: ${processResult.stdout}');
-    print('process stderr: ${processResult.stderr}');
-
-    var dir = new Directory(_Generator._outputDirectory == null? 'docs' :
-        _Generator._outputDirectory);
-    var webDocsDir = new Directory(path.join(_dartdocViewerDir.path, 'client',
-        'web', 'docs'));
-    if (dir.existsSync()) {
-      // Move the docs folder to dartdoc-viewer/client/web/docs
-      dir.renameSync(webDocsDir.path);
-    }
-
-    if (webDocsDir.existsSync()) {
+  static void _compile() {
+    if (_webDocsDir.existsSync()) {
       // Compile the code to JavaScript so we can run on any browser.
       print('Compile app to JavaScript for viewing.');
-      var processResult = Process.runSync('dart', ['deploy.dart'],
-          workingDirectory : path.join(_dartdocViewerDir.path, 'client'),
-          runInShell: true);
+      var processResult = Process.runSync(_Generator._dartBinary,
+          ['deploy.dart'], workingDirectory : path.join(_dartdocViewerDir.path,
+          'client'), runInShell: true);
       print('process output: ${processResult.stdout}');
       print('process stderr: ${processResult.stderr}');
-      _runServer();
+      var outputDir = path.join(_dartdocViewerDir.path, 'client', 'out', 'web');
+      print('Docs are available at $outputDir');
     }
   }
 
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 5f6ded3..ac95aee 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -421,43 +421,55 @@
 }
 
 
+void ClassFinalizer::ResolveTypeClass(const Class& cls,
+                                      const AbstractType& type) {
+  if (type.IsFinalized() || type.HasResolvedTypeClass()) {
+    return;
+  }
+  if (FLAG_trace_type_finalization) {
+    OS::Print("Resolve type class of '%s'\n",
+              String::Handle(type.Name()).ToCString());
+  }
+
+  // Type parameters are always resolved in the parser in the correct
+  // non-static scope or factory scope. That resolution scope is unknown here.
+  // Being able to resolve a type parameter from class cls here would indicate
+  // that the type parameter appeared in a static scope. Leaving the type as
+  // unresolved is the correct thing to do.
+
+  // Lookup the type class.
+  const UnresolvedClass& unresolved_class =
+      UnresolvedClass::Handle(type.unresolved_class());
+  const Class& type_class =
+      Class::Handle(ResolveClass(cls, unresolved_class));
+
+  // Replace unresolved class with resolved type class.
+  const Type& parameterized_type = Type::Cast(type);
+  if (type_class.IsNull()) {
+    // The type class could not be resolved. The type is malformed.
+    FinalizeMalformedType(
+        Error::Handle(),  // No previous error.
+        Script::Handle(cls.script()),
+        parameterized_type,
+        "cannot resolve class '%s' from '%s'",
+        String::Handle(unresolved_class.Name()).ToCString(),
+        String::Handle(cls.Name()).ToCString());
+    return;
+  }
+  parameterized_type.set_type_class(type_class);
+}
+
+
 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) {
-  if (type.IsResolved() || type.IsFinalized()) {
+  // TODO(regis): Add a kResolved bit in type_state_ for efficiency.
+  if (type.IsFinalized() || type.IsResolved()) {
     return;
   }
   if (FLAG_trace_type_finalization) {
     OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString());
   }
 
-  // Resolve the type class.
-  if (!type.HasResolvedTypeClass()) {
-    // Type parameters are always resolved in the parser in the correct
-    // non-static scope or factory scope. That resolution scope is unknown here.
-    // Being able to resolve a type parameter from class cls here would indicate
-    // that the type parameter appeared in a static scope. Leaving the type as
-    // unresolved is the correct thing to do.
-
-    // Lookup the type class.
-    const UnresolvedClass& unresolved_class =
-        UnresolvedClass::Handle(type.unresolved_class());
-    const Class& type_class =
-        Class::Handle(ResolveClass(cls, unresolved_class));
-
-    // Replace unresolved class with resolved type class.
-    const Type& parameterized_type = Type::Cast(type);
-    if (type_class.IsNull()) {
-      // The type class could not be resolved. The type is malformed.
-      FinalizeMalformedType(
-          Error::Handle(),  // No previous error.
-          Script::Handle(cls.script()),
-          parameterized_type,
-          "cannot resolve class '%s' from '%s'",
-          String::Handle(unresolved_class.Name()).ToCString(),
-          String::Handle(cls.Name()).ToCString());
-      return;
-    }
-    parameterized_type.set_type_class(type_class);
-  }
+  ResolveTypeClass(cls, type);
 
   // Resolve type arguments, if any.
   const TypeArguments& arguments = TypeArguments::Handle(type.arguments());
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 9e1d8bd..638e571 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -97,6 +97,9 @@
   // needed during bootstrapping where the classes have been preloaded.
   static void VerifyBootstrapClasses();
 
+  // Resolve the class of the type, but not the type's type arguments.
+  static void ResolveTypeClass(const Class& cls, const AbstractType& type);
+
   // Resolve the class of the type and the class of the type's type arguments.
   static void ResolveType(const Class& cls, const AbstractType& type);
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 33216e7..8720418 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2116,7 +2116,7 @@
       break;
     }
     sup_type = cls.super_type();
-    ClassFinalizer::ResolveType(cls, sup_type);
+    ClassFinalizer::ResolveTypeClass(cls, sup_type);
     cls = sup_type.type_class();
   } while (true);
   set_num_type_arguments(num_type_args);
diff --git a/sdk/bin/docgen b/sdk/bin/docgen
index b6822fa..db0c6af 100755
--- a/sdk/bin/docgen
+++ b/sdk/bin/docgen
@@ -18,17 +18,18 @@
 # Handle the case where dart-sdk/bin has been symlinked to.
 BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
 
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
 unset SNAPSHOT
 
 SNAPSHOT="$BIN_DIR/snapshots/utils_wrapper.dart.snapshot"
 
 if test -f $SNAPSHOT; then
-  # TODO(ahe): Remove the following line when we are relatively sure it works.
-  echo Using snapshot $SNAPSHOT 1>&2
   exec "$BIN_DIR"/dart \
-      "--package-root=$BIN_DIR/../packages/" $SNAPSHOT docgen "$@"
+      "--package-root=$BIN_DIR/../packages/" $SNAPSHOT \
+      docgen "--sdk=$SDK_DIR" "$@"
 else
   exec "$BIN_DIR"/dart \
       "--package-root=$BIN_DIR/../packages/" \
-      "$BIN_DIR/../pkg/docgen/bin/docgen.dart" "$@"
+      "$BIN_DIR/../../pkg/docgen/bin/docgen.dart" "--sdk=$SDK_DIR" "$@"
 fi
diff --git a/sdk/bin/docgen.bat b/sdk/bin/docgen.bat
index a199c4be..220703a 100644
--- a/sdk/bin/docgen.bat
+++ b/sdk/bin/docgen.bat
@@ -25,9 +25,9 @@
 
 set BUILD_DIR=%SDK_DIR%\..\build\%DART_CONFIGURATION%
 if exist "%SNAPSHOT%" (
-  "%DART%" "%SNAPSHOT%" "docgen" %*
+  "%DART%" "%SNAPSHOT%" "docgen" "--sdk=%SDK_DIR" %*
 ) else (
-  "%BUILD_DIR%\dart-sdk\bin\dart" "--package-root=%BUILD_DIR%\packages" "%DOCGEN%" %*
+  "%BUILD_DIR%\dart-sdk\bin\dart" "--package-root=%BUILD_DIR%\packages" "%DOCGEN%" "--sdk=%SDK_DIR" %*
 )
 
 endlocal
diff --git a/tests/language/regress_16640_test.dart b/tests/language/regress_16640_test.dart
new file mode 100644
index 0000000..64d8654
--- /dev/null
+++ b/tests/language/regress_16640_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 16640.
+
+class Segment extends SegmentGen { }
+
+class SegmentGen extends ConceptEntity<Segment> { }
+
+class ConceptEntity<E> { }
+
+main() {
+  new ConceptEntity<Segment>();
+}
diff --git a/tools/VERSION b/tools/VERSION
index 8a14351..9a19a4b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 2
 PATCH 0
 PRERELEASE 5
-PRERELEASE_PATCH 1
+PRERELEASE_PATCH 2