Removed dart:cli usage, use dylib version from ffigen's pubspec.yaml (#88)

* removed dart:cli usage, use dylib version from pubspec.lock
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5fc842d..6dfc92d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 0.2.3+3
+- Wrapper dynamic library version now uses ffigen version from its pubspec.yaml file.
+
 # 0.2.3+2
 - Handle code formatting using dartfmt by finding dart-sdk.
 
diff --git a/bin/ffigen.dart b/bin/ffigen.dart
index 74021be..d096914 100644
--- a/bin/ffigen.dart
+++ b/bin/ffigen.dart
@@ -13,7 +13,7 @@
 
 import 'setup.dart';
 
-var _logger = Logger('ffigen.ffigen');
+final _logger = Logger('ffigen.ffigen');
 final _ansi = Ansi(Ansi.terminalSupportsAnsi);
 
 String successPen(String str) {
@@ -28,24 +28,25 @@
   // Parses the cmd args. This will print usage and exit if --help was passed.
   final argResult = getArgResults(args);
 
+  // Setup logging level and printing.
+  setupLogger(argResult);
+
   /// Prompt user if dylib doesn't exist and cannot be auto created to run
   /// `pub run ffigen:setup -Ipath/to/llvm/include -Lpath/to/llvm/lib`.
   if (!checkDylibExist() && !autoCreateDylib()) {
-    print('Unable to create dynamic library automatically.');
-    print('If LLVM is installed, try running:');
-    print('  pub run ffigen:setup -Ipath/to/llvm/include -Lpath/to/llvm/lib');
+    _logger.severe('Unable to create dynamic library automatically.');
+    _logger.severe('If LLVM is installed, try running:');
+    _logger.severe(
+        '  pub run ffigen:setup -Ipath/to/llvm/include -Lpath/to/llvm/lib');
     exit(1);
   }
 
-  // Setup logging level and printing.
-  setupLogger(argResult);
-
   // Create a config object.
   Config config;
   try {
     config = getConfig(argResult);
   } on FormatException {
-    print('Please fix configuration errors and re-run the tool.');
+    _logger.severe('Please fix configuration errors and re-run the tool.');
     exit(1);
   }
 
diff --git a/lib/src/code_generator/library.dart b/lib/src/code_generator/library.dart
index 9503ee6..2daa009 100644
--- a/lib/src/code_generator/library.dart
+++ b/lib/src/code_generator/library.dart
@@ -12,7 +12,7 @@
 import 'utils.dart';
 import 'writer.dart';
 
-var _logger = Logger('ffigen.code_generator.library');
+final _logger = Logger('ffigen.code_generator.library');
 
 /// Container for all Bindings.
 class Library {
diff --git a/lib/src/config_provider/config.dart b/lib/src/config_provider/config.dart
index 0a913ad..2b9df49 100644
--- a/lib/src/config_provider/config.dart
+++ b/lib/src/config_provider/config.dart
@@ -14,7 +14,7 @@
 import 'config_types.dart';
 import 'spec_utils.dart';
 
-var _logger = Logger('ffigen.config_provider.config');
+final _logger = Logger('ffigen.config_provider.config');
 
 /// Provides configurations to other modules.
 ///
diff --git a/lib/src/config_provider/spec_utils.dart b/lib/src/config_provider/spec_utils.dart
index ddf6b89..1400c2f 100644
--- a/lib/src/config_provider/spec_utils.dart
+++ b/lib/src/config_provider/spec_utils.dart
@@ -14,7 +14,7 @@
 import '../strings.dart' as strings;
 import 'config_types.dart';
 
-var _logger = Logger('ffigen.config_provider.spec_utils');
+final _logger = Logger('ffigen.config_provider.spec_utils');
 
 /// Replaces the path separators according to current platform.
 String _replaceSeparators(String path) {
diff --git a/lib/src/find_resource.dart b/lib/src/find_resource.dart
index e9a9dae..7a8df1a 100644
--- a/lib/src/find_resource.dart
+++ b/lib/src/find_resource.dart
@@ -2,7 +2,95 @@
 // 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.
 
-library find_resource;
+import 'dart:convert' show jsonDecode;
+import 'dart:io' show File, Directory;
 
-export 'find_resource/find_resource_fallback.dart'
-    if (dart.library.cli) 'find_resource/find_resource_cli.dart';
+import 'package:logging/logging.dart';
+import 'package:yaml/yaml.dart';
+
+final _logger = Logger('ffigen.find_resource');
+
+/// Find the `.dart_tool/` folder, returns `null` if unable to find it.
+Uri findDotDartTool() {
+  // HACK: Because 'dart:isolate' is unavailable in Flutter we have no means
+  //       by which we can find the location of the package_config.json file.
+  //       Which we need, because the binary library created by:
+  //         flutter pub run ffigen:setup
+  //       is located relative to this path. As a workaround we use
+  //       `Platform.script` and traverse level-up until we find a
+  //       `.dart_tool/package_config.json` file.
+  // Find script directory
+  var root = Directory.current.uri;
+  // Traverse up until we see a `.dart_tool/package_config.json` file.
+  do {
+    if (File.fromUri(root.resolve('.dart_tool/package_config.json'))
+        .existsSync()) {
+      return root.resolve('.dart_tool/');
+    }
+  } while (root != (root = root.resolve('..')));
+  return null;
+}
+
+/// Get [Uri] for [posixPath] inside ffigen's rootUri.
+Uri _findInPackageRoot(String posixPath) {
+  var root = Directory.current.uri;
+  // Traverse up until we see a `.dart_tool/package_config.json` file.
+  do {
+    final file = File.fromUri(root.resolve('.dart_tool/package_config.json'));
+    if (file.existsSync()) {
+      /// Read the package_config.json file to extract path of wrapper.
+      try {
+        final packageMap =
+            jsonDecode(file.readAsStringSync()) as Map<String, dynamic>;
+        if (packageMap['configVersion'] == 2) {
+          var ffigenRootUriString = ((packageMap['packages'] as List<dynamic>)
+                  .cast<Map<String, dynamic>>()
+                  .firstWhere(
+                      (element) => element['name'] == 'ffigen')['rootUri']
+              as String);
+          ffigenRootUriString = ffigenRootUriString.endsWith('/')
+              ? ffigenRootUriString
+              : ffigenRootUriString + '/';
+
+          /// [ffigenRootUri] can be relative to .dart_tool if its from
+          /// filesystem so we need to resolve it from .dart_tool first.
+          return file.parent.uri
+              .resolve(ffigenRootUriString)
+              .resolve(posixPath);
+        }
+      } catch (e, s) {
+        print(s);
+        throw Exception('Cannot resolve package:ffigen\'s rootUri.');
+      }
+    }
+  } while (root != (root = root.resolve('..')));
+  return null;
+}
+
+Uri findWrapper(String wrapperName) {
+  return _findInPackageRoot('lib/src/clang_library/$wrapperName');
+}
+
+Uri _findFfigenPubspecYaml() {
+  return _findInPackageRoot('pubspec.yaml');
+}
+
+String _ffigenVersion;
+
+/// Gets ffigen version from ffigen's pubspec.yaml
+String get ffigenVersion {
+  if (_ffigenVersion == null) {
+    try {
+      final yaml =
+          loadYaml(File.fromUri(_findFfigenPubspecYaml()).readAsStringSync())
+              as YamlMap;
+      final rawVersion = yaml['version'] as String;
+      // Sanitize name to be used as a file name.
+      _ffigenVersion =
+          'v_${rawVersion.replaceAll('.', '_').replaceAll('+', '_')}';
+    } catch (e) {
+      _logger.severe('Unable to extract ffigen version.');
+    }
+  }
+  return _ffigenVersion;
+}
diff --git a/lib/src/find_resource/find_resource_cli.dart b/lib/src/find_resource/find_resource_cli.dart
deleted file mode 100644
index d3885b5..0000000
--- a/lib/src/find_resource/find_resource_cli.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2020, 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.
-
-import 'dart:cli' as cli;
-import 'dart:io' show File;
-import 'dart:isolate' show Isolate;
-import 'find_resource_fallback.dart' as fallback;
-
-/// Find the `.dart_tool/` folder, returns `null` if unable to find it.
-Uri findDotDartTool() {
-  // Find [Isolate.packageConfig] and check if contains:
-  //  * `package_config.json`, or,
-  //  * `.dart_tool/package_config.json`.
-  // If either is the case we know the path to `.dart_tool/`.
-  final packageConfig = cli.waitFor(Isolate.packageConfig);
-  if (packageConfig != null &&
-      File.fromUri(packageConfig.resolve('package_config.json')).existsSync()) {
-    return packageConfig.resolve('./');
-  }
-  if (packageConfig != null &&
-      File.fromUri(packageConfig.resolve('.dart_tool/package_config.json'))
-          .existsSync()) {
-    return packageConfig.resolve('.dart_tool/');
-  }
-  // If [Isolate.packageConfig] isn't helpful we fallback to looking at the
-  // current script location and traverse up from there.
-  return fallback.findDotDartTool();
-}
-
-Uri findWrapper(String wrapperName) {
-  final wrapperUri = cli.waitFor(Isolate.resolvePackageUri(
-      Uri.parse('package:ffigen/src/clang_library/$wrapperName')));
-  // If [Isolate.packageConfig] isn't helpful we fallback to looking at the
-  // current script location and traverse up from there.
-  return wrapperUri ?? fallback.findWrapper(wrapperName);
-}
diff --git a/lib/src/find_resource/find_resource_fallback.dart b/lib/src/find_resource/find_resource_fallback.dart
deleted file mode 100644
index 0db61ee..0000000
--- a/lib/src/find_resource/find_resource_fallback.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2020, 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.
-
-import 'dart:convert' show jsonDecode;
-import 'dart:io' show File, Directory;
-
-/// Find the `.dart_tool/` folder, returns `null` if unable to find it.
-Uri findDotDartTool() {
-  // HACK: Because 'dart:isolate' is unavailable in Flutter we have no means
-  //       by which we can find the location of the package_config.json file.
-  //       Which we need, because the binary library created by:
-  //         flutter pub run ffigen:setup
-  //       is located relative to this path. As a workaround we use
-  //       `Platform.script` and traverse level-up until we find a
-  //       `.dart_tool/package_config.json` file.
-  // Find script directory
-  var root = Directory.current.uri;
-  // Traverse up until we see a `.dart_tool/package_config.json` file.
-  do {
-    if (File.fromUri(root.resolve('.dart_tool/package_config.json'))
-        .existsSync()) {
-      return root.resolve('.dart_tool/');
-    }
-  } while (root != (root = root.resolve('..')));
-  return null;
-}
-
-Uri findWrapper(String wrapperName) {
-  var root = Directory.current.uri;
-  // Traverse up until we see a `.dart_tool/package_config.json` file.
-  do {
-    final file = File.fromUri(root.resolve('.dart_tool/package_config.json'));
-    if (file.existsSync()) {
-      /// Read the package_config.json file to extract path of wrapper.
-      try {
-        final packageMap =
-            jsonDecode(file.readAsStringSync()) as Map<String, dynamic>;
-        if (packageMap['configVersion'] == 2) {
-          var ffigenRootUriString = ((packageMap['packages'] as List<dynamic>)
-                  .cast<Map<String, dynamic>>()
-                  .firstWhere(
-                      (element) => element['name'] == 'ffigen')['rootUri']
-              as String);
-          ffigenRootUriString = ffigenRootUriString.endsWith('/')
-              ? ffigenRootUriString
-              : ffigenRootUriString + '/';
-
-          /// [ffigenRootUri] can be relative to .dart_tool if its from
-          /// filesystem so we need to resolve it from .dart_tool first.
-          return file.parent.uri
-              .resolve(ffigenRootUriString)
-              .resolve('lib/src/clang_library/$wrapperName');
-        }
-      } catch (e, s) {
-        print(s);
-        throw Exception('Cannot resolve package:ffigen\'s rootUri.');
-      }
-    }
-  } while (root != (root = root.resolve('..')));
-  return null;
-}
diff --git a/lib/src/header_parser/parser.dart b/lib/src/header_parser/parser.dart
index c5698b0..4036a4c 100644
--- a/lib/src/header_parser/parser.dart
+++ b/lib/src/header_parser/parser.dart
@@ -42,7 +42,7 @@
 //           BELOW FUNCTIONS ARE MEANT FOR INTERNAL USE AND TESTING
 // ===================================================================================
 
-var _logger = Logger('ffigen.header_parser.parser');
+final _logger = Logger('ffigen.header_parser.parser');
 
 /// Initializes parser, clears any previous values.
 void initParser(Config c) {
diff --git a/lib/src/header_parser/sub_parsers/enumdecl_parser.dart b/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
index 50248a6..49e4b1a 100644
--- a/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
@@ -14,7 +14,7 @@
 import '../includer.dart';
 import '../utils.dart';
 
-var _logger = Logger('ffigen.header_parser.enumdecl_parser');
+final _logger = Logger('ffigen.header_parser.enumdecl_parser');
 
 /// Holds temporary information regarding [EnumClass] while parsing.
 class _ParsedEnum {
@@ -89,7 +89,7 @@
         _addEnumConstantToEnumClass(cursor);
         break;
       default:
-        print('invalid enum constant');
+        _logger.fine('invalid enum constant');
     }
     cursor.dispose();
     parent.dispose();
diff --git a/lib/src/header_parser/sub_parsers/functiondecl_parser.dart b/lib/src/header_parser/sub_parsers/functiondecl_parser.dart
index 78d52b4..3be5c1e 100644
--- a/lib/src/header_parser/sub_parsers/functiondecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/functiondecl_parser.dart
@@ -13,7 +13,7 @@
 import '../includer.dart';
 import '../utils.dart';
 
-var _logger = Logger('ffigen.header_parser.functiondecl_parser');
+final _logger = Logger('ffigen.header_parser.functiondecl_parser');
 
 /// Holds temporary information regarding [Func] while parsing.
 class _ParserFunc {
diff --git a/lib/src/header_parser/sub_parsers/macro_parser.dart b/lib/src/header_parser/sub_parsers/macro_parser.dart
index ad9df56..8884dd5 100644
--- a/lib/src/header_parser/sub_parsers/macro_parser.dart
+++ b/lib/src/header_parser/sub_parsers/macro_parser.dart
@@ -16,7 +16,7 @@
 import '../data.dart';
 import '../utils.dart';
 
-var _logger = Logger('ffigen.header_parser.macro_parser');
+final _logger = Logger('ffigen.header_parser.macro_parser');
 
 /// Adds a macro definition to be parsed later.
 void saveMacroDefinition(Pointer<clang_types.CXCursor> cursor) {
diff --git a/lib/src/header_parser/sub_parsers/structdecl_parser.dart b/lib/src/header_parser/sub_parsers/structdecl_parser.dart
index 44ece8d..9b19d54 100644
--- a/lib/src/header_parser/sub_parsers/structdecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/structdecl_parser.dart
@@ -12,7 +12,7 @@
 import '../includer.dart';
 import '../utils.dart';
 
-var _logger = Logger('ffigen.header_parser.structdecl_parser');
+final _logger = Logger('ffigen.header_parser.structdecl_parser');
 
 /// Holds temporary information regarding [struc] while parsing.
 class _ParsedStruc {
diff --git a/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart b/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
index 558fce3..3801dde 100644
--- a/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
@@ -13,7 +13,7 @@
 import '../sub_parsers/structdecl_parser.dart';
 import '../utils.dart';
 
-var _logger = Logger('ffigen.header_parser.typedefdecl_parser');
+final _logger = Logger('ffigen.header_parser.typedefdecl_parser');
 
 /// Holds temporary information regarding a typedef referenced [Binding]
 /// while parsing.
diff --git a/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart b/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart
index 713fae0..729f791 100644
--- a/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart
@@ -12,7 +12,7 @@
 import '../data.dart';
 import '../utils.dart';
 
-var _logger = Logger('ffigen.header_parser.unnamed_enumdecl_parser');
+final _logger = Logger('ffigen.header_parser.unnamed_enumdecl_parser');
 
 /// Saves unnamed enums.
 void saveUnNamedEnum(Pointer<clang_types.CXCursor> cursor) {
diff --git a/lib/src/header_parser/translation_unit_parser.dart b/lib/src/header_parser/translation_unit_parser.dart
index f576fae..5ca8997 100644
--- a/lib/src/header_parser/translation_unit_parser.dart
+++ b/lib/src/header_parser/translation_unit_parser.dart
@@ -17,7 +17,7 @@
 import 'sub_parsers/typedefdecl_parser.dart';
 import 'utils.dart';
 
-var _logger = Logger('ffigen.header_parser.translation_unit_parser');
+final _logger = Logger('ffigen.header_parser.translation_unit_parser');
 
 Set<Binding> _bindings;
 
diff --git a/lib/src/header_parser/type_extractor/extractor.dart b/lib/src/header_parser/type_extractor/extractor.dart
index a198420..0e6ec0f 100644
--- a/lib/src/header_parser/type_extractor/extractor.dart
+++ b/lib/src/header_parser/type_extractor/extractor.dart
@@ -15,7 +15,7 @@
 import '../type_extractor/cxtypekindmap.dart';
 import '../utils.dart';
 
-var _logger = Logger('ffigen.header_parser.extractor');
+final _logger = Logger('ffigen.header_parser.extractor');
 const _padding = '  ';
 
 /// Converts cxtype to a typestring code_generator can accept.
diff --git a/lib/src/strings.dart b/lib/src/strings.dart
index 9337fa1..53bd07f 100644
--- a/lib/src/strings.dart
+++ b/lib/src/strings.dart
@@ -3,11 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 import 'dart:io';
 
+import 'package:ffigen/src/find_resource.dart';
 import 'package:ffigen/src/header_parser/clang_bindings/clang_bindings.dart'
     as clang;
 
-// This version must be updated whenever we update the libclang wrapper.
-const dylibVersion = 'v4';
+String get dylibVersion => ffigenVersion;
 
 /// Name of the dynamic library file according to current platform.
 String get dylibFileName {
diff --git a/pubspec.yaml b/pubspec.yaml
index 1db827c..57443c8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 name: ffigen
-version: 0.2.3+2
+version: 0.2.3+3
 homepage: https://github.com/dart-lang/ffigen
 description: Experimental generator for FFI bindings, using LibClang to parse C/C++ header files.