Chromium Code Reviews

Unified Diff: pkg/dev_compiler/lib/src/compiler/extension_types.dart

Issue 2757753002: Migrate DDC to the new analysis driver.
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Index: pkg/dev_compiler/lib/src/compiler/extension_types.dart
diff --git a/pkg/dev_compiler/lib/src/compiler/extension_types.dart b/pkg/dev_compiler/lib/src/compiler/extension_types.dart
index 1e26fb46598c49dc8d9497d8dcc3cfd41001c060..383f7da46a76747c1b739cb2f2935c0c6a0bc9e0 100644
--- a/pkg/dev_compiler/lib/src/compiler/extension_types.dart
+++ b/pkg/dev_compiler/lib/src/compiler/extension_types.dart
@@ -2,11 +2,14 @@
// 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:async';
import 'dart:collection';
+
import 'package:analyzer/dart/element/element.dart'
show ClassElement, CompilationUnitElement, Element;
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart' show DartType, InterfaceType;
-import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/dart/analysis/driver.dart';
/// Contains information about native JS types (those types provided by the
/// implementation) that are also provided by the Dart SDK.
@@ -26,66 +29,32 @@ import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
/// This will provide the [Iterable.first] property, without needing to add
/// `first` to the `Array.prototype`.
class ExtensionTypeSet {
- final AnalysisContext _context;
+ final AnalysisDriver _driver;
- // Abstract types that may be implemented by both native and non-native
- // classes.
+ /// Abstract types that may be implemented by both native and non-native
+ /// classes.
final _extensibleTypes = new HashSet<ClassElement>();
- // Concrete native types.
+ /// Concrete native types.
final _nativeTypes = new HashSet<ClassElement>();
- final _pendingLibraries = new HashSet<String>();
- ExtensionTypeSet(this._context) {
- // TODO(vsm): Eventually, we want to make this extensible - i.e., find
- // annotations in user code as well. It would need to be summarized in
- // the element model - not searched this way on every compile. To make this
- // a little more efficient now, we do this in two phases.
+ ExtensionTypeSet._(this._driver);
- // First, core types:
- // TODO(vsm): If we're analyzing against the main SDK, those
- // types are not explicitly annotated.
- var types = _context.typeProvider;
- _addExtensionType(types.intType, true);
- _addExtensionType(types.doubleType, true);
- _addExtensionType(types.boolType, true);
- _addExtensionType(types.stringType, true);
- _addExtensionTypes('dart:_interceptors');
- _addExtensionTypes('dart:_native_typed_data');
-
- // These are used natively by dart:html but also not annotated.
- _addExtensionTypesForLibrary('dart:core', ['Comparable', 'Map']);
- _addExtensionTypesForLibrary('dart:collection', ['ListMixin']);
- _addExtensionTypesForLibrary('dart:math', ['Rectangle']);
-
- // Second, html types - these are only searched if we use dart:html, etc.:
- _addPendingExtensionTypes('dart:html');
- _addPendingExtensionTypes('dart:indexed_db');
- _addPendingExtensionTypes('dart:svg');
- _addPendingExtensionTypes('dart:web_audio');
- _addPendingExtensionTypes('dart:web_gl');
- _addPendingExtensionTypes('dart:web_sql');
+ /// Collects all supertypes that may themselves contain native subtypes,
+ /// excluding [Object], for example `List` is implemented by several native
+ /// types.
+ LinkedHashSet<ClassElement> collectNativeInterfaces(ClassElement element) {
+ var types = new LinkedHashSet<ClassElement>();
+ _collectNativeInterfaces(element.type, types);
+ return types;
}
- void _visitCompilationUnit(CompilationUnitElement unit) {
- unit.types.forEach(_visitClass);
- }
+ bool hasNativeSubtype(DartType type) =>
+ isNativeInterface(type.element) || isNativeClass(type.element);
- void _visitClass(ClassElement element) {
- if (_isNative(element)) {
- _addExtensionType(element.type, true);
- }
- }
+ bool isNativeClass(Element element) => _nativeTypes.contains(element);
- bool _isNative(ClassElement element) {
- for (var metadata in element.metadata) {
- var e = metadata.element?.enclosingElement;
- if (e.name == 'Native' || e.name == 'JsPeerInterface') {
- if (e.source.isInSystemLibrary) return true;
- }
- }
- return false;
- }
+ bool isNativeInterface(Element element) => _extensibleTypes.contains(element);
void _addExtensionType(InterfaceType t, [bool mustBeNative = false]) {
if (t.isObject) return;
@@ -104,59 +73,19 @@ class ExtensionTypeSet {
_addExtensionType(element.supertype);
}
- void _addExtensionTypesForLibrary(String libraryUri, List<String> typeNames) {
- var sourceFactory = _context.sourceFactory.forUri(libraryUri);
- var library = _context.computeLibraryElement(sourceFactory);
- for (var typeName in typeNames) {
- _addExtensionType(library.getType(typeName).type);
- }
- }
-
- void _addExtensionTypes(String libraryUri) {
- var sourceFactory = _context.sourceFactory.forUri(libraryUri);
- var library = _context.computeLibraryElement(sourceFactory);
+ Future<Null> _addExtensionTypes(String libraryUri) async {
+ LibraryElement library = await _computeLibraryByUri(libraryUri);
_visitCompilationUnit(library.definingCompilationUnit);
library.parts.forEach(_visitCompilationUnit);
}
- void _addPendingExtensionTypes(String libraryUri) {
- _pendingLibraries.add(libraryUri);
- }
-
- bool _processPending(Element element) {
- if (_pendingLibraries.isEmpty) return false;
- if (element is ClassElement) {
- var uri = element.library.source.uri.toString();
- if (_pendingLibraries.contains(uri)) {
- // Load all pending libraries
- _pendingLibraries.forEach(_addExtensionTypes);
- _pendingLibraries.clear();
- return true;
- }
+ Future<Null> _addExtensionTypesForLibrary(
+ String libraryUri, List<String> typeNames,
+ [bool mustBeNative = false]) async {
+ LibraryElement library = await _computeLibraryByUri(libraryUri);
+ for (var typeName in typeNames) {
+ _addExtensionType(library.getType(typeName).type, mustBeNative);
}
- return false;
- }
-
- bool _setContains(HashSet<ClassElement> set, Element element) {
- return set.contains(element) ||
- _processPending(element) && set.contains(element);
- }
-
- bool isNativeClass(Element element) => _setContains(_nativeTypes, element);
-
- bool isNativeInterface(Element element) =>
- _setContains(_extensibleTypes, element);
-
- bool hasNativeSubtype(DartType type) =>
- isNativeInterface(type.element) || isNativeClass(type.element);
-
- /// Collects all supertypes that may themselves contain native subtypes,
- /// excluding [Object], for example `List` is implemented by several native
- /// types.
- LinkedHashSet<ClassElement> collectNativeInterfaces(ClassElement element) {
- var types = new LinkedHashSet<ClassElement>();
- _collectNativeInterfaces(element.type, types);
- return types;
}
void _collectNativeInterfaces(InterfaceType type, Set<ClassElement> types) {
@@ -171,4 +100,62 @@ class ExtensionTypeSet {
}
_collectNativeInterfaces(element.supertype, types);
}
+
+ Future<LibraryElement> _computeLibraryByUri(String libraryUri) async {
+ return await _driver.resynthesizeLibrary(libraryUri);
+ }
+
+ Future<Null> _initialize() async {
Jennifer Messerly 2017/03/17 18:33:38 similar comment here; I would prefer to factor thi
scheglov 2017/04/25 17:07:35 Done.
+ // TODO(vsm): Eventually, we want to make this extensible - i.e., find
+ // annotations in user code as well. It would need to be summarized in
+ // the element model - not searched this way on every compile. To make this
+ // a little more efficient now, we do this in two phases.
+
+ // First, core types:
+ // TODO(vsm): If we're analyzing against the main SDK, those
+ // types are not explicitly annotated.
+ await _addExtensionTypesForLibrary(
+ 'dart:core', ['int', 'double', 'bool', 'String'], true);
+ await _addExtensionTypes('dart:_interceptors');
+ await _addExtensionTypes('dart:_native_typed_data');
+
+ // These are used natively by dart:html but also not annotated.
+ await _addExtensionTypesForLibrary('dart:core', ['Comparable', 'Map']);
+ await _addExtensionTypesForLibrary('dart:collection', ['ListMixin']);
+ await _addExtensionTypesForLibrary('dart:math', ['Rectangle']);
+
+ // Second, html types - these are only searched if we use dart:html, etc.:
+ await _addExtensionTypes('dart:html');
+ await _addExtensionTypes('dart:indexed_db');
+ await _addExtensionTypes('dart:svg');
+ await _addExtensionTypes('dart:web_audio');
+ await _addExtensionTypes('dart:web_gl');
+ await _addExtensionTypes('dart:web_sql');
+ }
+
+ bool _isNative(ClassElement element) {
+ for (var metadata in element.metadata) {
+ var e = metadata.element?.enclosingElement;
+ if (e.name == 'Native' || e.name == 'JsPeerInterface') {
+ if (e.source.isInSystemLibrary) return true;
+ }
+ }
+ return false;
+ }
+
+ void _visitClass(ClassElement element) {
+ if (_isNative(element)) {
+ _addExtensionType(element.type, true);
+ }
+ }
+
+ void _visitCompilationUnit(CompilationUnitElement unit) {
+ unit.types.forEach(_visitClass);
+ }
+
+ static Future<ExtensionTypeSet> create(AnalysisDriver driver) async {
+ var typeSet = new ExtensionTypeSet._(driver);
+ await typeSet._initialize();
+ return typeSet;
+ }
}

Powered by Google App Engine