Support jsinterop/world_test from .dill
R=sigmund@google.com Review-Url: https://codereview.chromium.org/2995643002 .
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user