Support jsinterop/world_test from .dill

R=sigmund@google.com

Review-Url: https://codereview.chromium.org/2995643002 .
This commit is contained in:
Johnni Winther
2017-08-10 10:13:19 +02:00
parent 437b00c9e8
commit fd81ba4569
7 changed files with 79 additions and 20 deletions
@@ -291,9 +291,31 @@ class NativeBasicDataImpl implements NativeBasicData {
return jsInteropClasses.containsKey(element);
}
bool _isJsInteropMember(MemberEntity element) {
return jsInteropMembers.containsKey(element);
}
@override
bool isJsInteropMember(MemberEntity element) {
return jsInteropMembers.containsKey(element);
// TODO(johnniwinther): Share this with [NativeDataImpl.isJsInteropMember].
if (element.isFunction ||
element.isConstructor ||
element.isGetter ||
element.isSetter) {
FunctionEntity function = element;
if (!function.isExternal) return false;
if (_isJsInteropMember(function)) return true;
if (function.enclosingClass != null) {
return isJsInteropClass(function.enclosingClass);
}
if (function.isTopLevel) {
return isJsInteropLibrary(function.library);
}
return false;
} else {
return _isJsInteropMember(element);
}
}
@override
+3 -2
View File
@@ -142,8 +142,9 @@ abstract class KernelToElementMapForImpact extends KernelToElementMap {
/// Computes the native behavior for writing to the native [field].
native.NativeBehavior getNativeBehaviorForFieldStore(ir.Field field);
/// Computes the native behavior for calling [procedure].
native.NativeBehavior getNativeBehaviorForMethod(ir.Procedure procedure,
/// Computes the native behavior for calling the function or constructor
/// [member].
native.NativeBehavior getNativeBehaviorForMethod(ir.Member member,
{bool isJsInterop});
/// Compute the kind of foreign helper function called by [node], if any.
@@ -402,12 +402,19 @@ abstract class KernelToElementMapForImpactMixin
return nativeBehaviorBuilder.buildFieldStoreBehavior(type);
}
/// Computes the native behavior for calling [procedure].
/// Computes the native behavior for calling [member].
// TODO(johnniwinther): Cache this for later use.
native.NativeBehavior getNativeBehaviorForMethod(ir.Procedure procedure,
native.NativeBehavior getNativeBehaviorForMethod(ir.Member member,
{bool isJsInterop}) {
DartType type = getFunctionType(procedure.function);
List<ConstantValue> metadata = getMetadata(procedure.annotations);
DartType type;
if (member is ir.Procedure) {
type = getFunctionType(member.function);
} else if (member is ir.Constructor) {
type = getFunctionType(member.function);
} else {
failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected method node $member.");
}
List<ConstantValue> metadata = getMetadata(member.annotations);
return nativeBehaviorBuilder.buildMethodBehavior(
type, metadata, typeLookup(resolveAsRaw: false),
isJsInterop: isJsInterop);
@@ -129,18 +129,33 @@ class KernelAnnotationProcessor implements AnnotationProcessor {
{'cls': cls.name, 'member': member.name});
}
if (function is ConstructorEntity &&
function.isFactoryConstructor &&
isAnonymous) {
if (function.parameterStructure.requiredParameters > 0) {
checkFunctionParameters(function);
});
elementEnvironment.forEachConstructor(cls,
(ConstructorEntity constructor) {
String memberName = getJsInteropName(
library, elementEnvironment.getMemberMetadata(constructor));
if (memberName != null) {
_nativeBasicDataBuilder.markAsJsInteropMember(
constructor, memberName);
}
if (!constructor.isExternal) {
reporter.reportErrorMessage(
constructor,
MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
{'cls': cls.name, 'member': constructor.name});
}
if (constructor.isFactoryConstructor && isAnonymous) {
if (constructor.parameterStructure.requiredParameters > 0) {
reporter.reportErrorMessage(
function,
constructor,
MessageKind
.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
{'cls': cls.name});
}
} else {
checkFunctionParameters(function);
checkFunctionParameters(constructor);
}
});
}
@@ -137,6 +137,14 @@ class KernelImpactBuilder extends ir.Visitor {
handleSignature(constructor.function, checkReturnType: false);
visitNodes(constructor.initializers);
visitNode(constructor.function.body);
if (constructor.isExternal &&
!elementAdapter.isForeignLibrary(constructor.enclosingLibrary)) {
MemberEntity member = elementAdapter.getMember(constructor);
bool isJsInterop =
elementAdapter.nativeBasicData.isJsInteropMember(member);
impactBuilder.registerNativeData(elementAdapter
.getNativeBehaviorForMethod(constructor, isJsInterop: isJsInterop));
}
return impactBuilder;
}
@@ -15,11 +15,12 @@ import '../type_test_helper.dart';
void main() {
asyncTest(() async {
await testClasses();
await testClasses(CompileMode.memory);
await testClasses(CompileMode.dill);
});
}
testClasses() async {
testClasses(CompileMode compileMode) async {
test(String mainSource,
{List<String> directlyInstantiated: const <String>[],
List<String> abstractlyInstantiated: const <String>[],
@@ -77,7 +78,7 @@ newF() => new F(5);
import 'package:js/js.dart';
$mainSource
""", compileMode: CompileMode.memory);
""", compileMode: compileMode);
Map<String, ClassEntity> classEnvironment = <String, ClassEntity>{};
ClassEntity registerClass(ClassEntity cls) {
@@ -30,9 +30,6 @@ import 'test_helpers.dart';
const Map<String, String> SOURCE = const <String, String>{
// Pretend this is a dart2js_native test to allow use of 'native' keyword.
'sdk/tests/compiler/dart2js_native/main.dart': r'''
@JS()
library test;
import 'dart:_foreign_helper' as foreign show JS;
import 'dart:_foreign_helper' hide JS;
import 'dart:_js_helper';
@@ -44,8 +41,8 @@ import 'dart:html_common';
import 'dart:math';
import 'dart:typed_data';
import 'dart:web_sql';
import 'package:js/js.dart';
import 'helper.dart';
import 'jsinterop.dart';
main() {
testEmpty();
@@ -698,12 +695,20 @@ testMixinInstantiation() => new Sub();
testNamedMixinInstantiation() => new NamedMixin();
testGenericMixinInstantiation() => new GenericSub<int, String>();
testGenericNamedMixinInstantiation() => new GenericNamedMixin<int, String>();
''',
'sdk/tests/compiler/dart2js_native/jsinterop.dart': '''
@JS()
library jsinterop;
import 'package:js/js.dart';
@JS()
external int testJsInteropMethod();
@JS()
class JsInteropClass {
external JsInteropClass();
@JS()
external double method();
}