Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(531)

Unified Diff: lib/src/codegen/js_codegen.dart

Issue 1680263002: Support for dart:typed_data (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Address comments, rebase Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/runtime/dart/typed_data.js ('k') | lib/src/codegen/js_interop.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/codegen/js_codegen.dart
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
index 64ab40352f67e3b22ff90d10b74a69ce7f324d7a..b41607f168acc516553c6ebae38e6797394e9a16 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -10,6 +10,7 @@ import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/generated/scanner.dart'
show StringToken, Token, TokenType;
@@ -218,10 +219,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
// String scriptTag = null;
// if (library.library.scriptTag != null) scriptTag = '/usr/bin/env $jsBin';
return moduleBuilder.build(
- currentModuleName,
- _jsModuleValue,
- _exportsVar,
- items);
+ currentModuleName, _jsModuleValue, _exportsVar, items);
}
void _emitModuleItem(AstNode node) {
@@ -439,9 +437,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
String jsPeerName;
var jsPeer = findAnnotation(classElem, isJsPeerInterface);
+ // Only look at "Native" annotations on registered extension types.
+ // E.g., we're current ignoring the ones in dart:html.
+ if (jsPeer == null && _extensionTypes.contains(classElem)) {
+ jsPeer = findAnnotation(classElem, isNativeAnnotation);
+ }
if (jsPeer != null) {
jsPeerName =
getConstantField(jsPeer, 'name', types.stringType)?.toStringValue();
+ if (jsPeerName.contains(',')) {
+ jsPeerName = jsPeerName.split(',')[0];
+ }
}
var body = _finishClassMembers(classElem, classExpr, ctors, fields,
@@ -1322,17 +1328,49 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
}
}
+ JS.Fun _emitNativeFunctionBody(
+ List<JS.Parameter> params, MethodDeclaration node) {
+ if (node.isStatic) {
+ // TODO(vsm): Do we need to handle this case?
+ return null;
+ }
+
+ String name = node.name.name;
+ var annotation = findAnnotation(node.element, isJsName);
+ if (annotation != null) {
+ name = getConstantField(annotation, 'name', types.stringType)
+ ?.toStringValue();
+ }
+ if (node.isGetter) {
+ return new JS.Fun(params, js.statement('{ return this.#; }', [name]));
+ } else if (node.isSetter) {
+ return new JS.Fun(
+ params, js.statement('{ this.# = #; }', [name, params.last]));
+ } else {
+ return new JS.Fun(
+ params, js.statement('{ return this.#(#); }', [name, params]));
+ }
+ }
+
JS.Method _emitMethodDeclaration(DartType type, MethodDeclaration node) {
- if (node.isAbstract || _externalOrNative(node)) {
+ if (node.isAbstract) {
return null;
}
var params = _visit(node.parameters) as List<JS.Parameter>;
if (params == null) params = <JS.Parameter>[];
- var typeParams = _emitTypeParams(node.element).toList();
- var returnType = emitTypeRef(node.element.returnType);
- JS.Fun fn = _emitFunctionBody(params, node.body, typeParams, returnType);
+ JS.Fun fn;
+ if (_externalOrNative(node)) {
+ fn = _emitNativeFunctionBody(params, node);
+ // TODO(vsm): Remove if / when we handle the static case above.
+ if (fn == null) return null;
+ } else {
+ var typeParams = _emitTypeParams(node.element).toList();
+ var returnType = emitTypeRef(node.element.returnType);
+ fn = _emitFunctionBody(params, node.body, typeParams, returnType);
+ }
+
if (node.operatorKeyword != null &&
node.name.name == '[]=' &&
params.isNotEmpty) {
@@ -2931,7 +2969,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
if (!_isObjectProperty(memberName)) {
return false;
}
- if (!type.isObject && !_isJSBuiltinType(type) && !_isNullable(target)) {
+ if (!type.isObject &&
+ !_isJSBuiltinType(type) &&
+ !_extensionTypes.contains(type.element) &&
+ !_isNullable(target)) {
return false;
}
return true;
@@ -3625,27 +3666,18 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
}
}
-class JSGenerator extends CodeGenerator {
- final _extensionTypes = new HashSet<ClassElement>();
+class _ExtensionFinder extends GeneralizingElementVisitor {
+ final AnalysisContext _context;
+ final HashSet<ClassElement> _extensionTypes;
final TypeProvider _types;
- JSGenerator(AbstractCompiler compiler)
- : _types = compiler.context.typeProvider,
- super(compiler) {
- // TODO(jacobr): determine the the set of types with extension methods from
- // the annotations rather than hard coding the list once the analyzer
- // supports summaries.
- var context = compiler.context;
- var src = context.sourceFactory.forUri('dart:_interceptors');
- var interceptors = context.computeLibraryElement(src);
- for (var t in ['JSArray', 'JSString', 'JSNumber', 'JSBool']) {
- _addExtensionType(interceptors.getType(t).type);
+
+ _ExtensionFinder(this._context, this._extensionTypes, this._types);
+
+ visitClassElement(ClassElement element) {
+ if (findAnnotation(element, isJsPeerInterface) != null ||
+ findAnnotation(element, isNativeAnnotation) != null) {
+ _addExtensionType(element.type);
}
- // TODO(jmesserly): manually add `int` and `double`
- // Unfortunately our current analyzer rejects "implements int".
- // Fix was landed, so we can remove this hack once we're updated:
- // https://github.com/dart-lang/sdk/commit/d7cd11f86a02f55269fc8d9843e7758ebeeb81c8
- _addExtensionType(_types.intType);
- _addExtensionType(_types.doubleType);
}
void _addExtensionType(InterfaceType t) {
@@ -3656,6 +3688,35 @@ class JSGenerator extends CodeGenerator {
_addExtensionType(t.superclass);
}
+ void _addExtensionTypes(String libraryUri) {
+ var sourceFactory = _context.sourceFactory.forUri(libraryUri);
+ var library = _context.computeLibraryElement(sourceFactory);
+ visitLibraryElement(library);
+ }
+}
+
+class JSGenerator extends CodeGenerator {
+ final _extensionTypes = new HashSet<ClassElement>();
+ final TypeProvider _types;
+
+ JSGenerator(AbstractCompiler compiler)
+ : _types = compiler.context.typeProvider,
+ super(compiler) {
+ // 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.
+ var finder = new _ExtensionFinder(context, _extensionTypes, _types);
+ finder._addExtensionTypes('dart:_interceptors');
+ finder._addExtensionTypes('dart:_native_typed_data');
+
+ // TODO(vsm): If we're analyzing against the main SDK, those
+ // types are not explicitly annotated.
+ finder._addExtensionType(_types.intType);
+ finder._addExtensionType(_types.doubleType);
+ finder._addExtensionType(_types.boolType);
+ finder._addExtensionType(_types.stringType);
+ }
+
String generateLibrary(LibraryUnit unit) {
// Clone the AST first, so we can mutate it.
unit = unit.clone();
« no previous file with comments | « lib/runtime/dart/typed_data.js ('k') | lib/src/codegen/js_interop.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698