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

Side by Side Diff: pkg/dev_compiler/lib/src/compiler/code_generator.dart

Issue 2515353003: Support lazy JS types. (Closed)
Patch Set: Support lazy JS types. Created 4 years 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 2
3 // for details. All rights reserved. Use of this source code is governed by a 3 // for details. All rights reserved. Use of this source code is governed by a
4 // BSD-style license that can be found in the LICENSE file. 4 // BSD-style license that can be found in the LICENSE file.
5 5
6 import 'dart:collection' show HashMap, HashSet; 6 import 'dart:collection' show HashMap, HashSet;
7 import 'dart:math' show min, max; 7 import 'dart:math' show min, max;
8 8
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 items.addAll(_typeTable.discharge()); 301 items.addAll(_typeTable.discharge());
302 302
303 // Add the module's code (produced by visiting compilation units, above) 303 // Add the module's code (produced by visiting compilation units, above)
304 _copyAndFlattenBlocks(items, _moduleItems); 304 _copyAndFlattenBlocks(items, _moduleItems);
305 305
306 // Build the module. 306 // Build the module.
307 return new JS.Program(items, name: _buildUnit.name); 307 return new JS.Program(items, name: _buildUnit.name);
308 } 308 }
309 309
310 List<String> _getJSName(Element e) { 310 List<String> _getJSName(Element e) {
311 if (findAnnotation(e.library, isPublicJSAnnotation) == null) { 311 if (e.library == null ||
312 findAnnotation(e.library, isPublicJSAnnotation) == null) {
312 return null; 313 return null;
313 } 314 }
314 315
315 var libraryJSName = getAnnotationName(e.library, isPublicJSAnnotation); 316 var libraryJSName = getAnnotationName(e.library, isPublicJSAnnotation);
316 var libraryPrefix = <String>[]; 317 var libraryPrefix = <String>[];
317 if (libraryJSName != null && libraryJSName.isNotEmpty) { 318 if (libraryJSName != null && libraryJSName.isNotEmpty) {
318 libraryPrefix.addAll(libraryJSName.split('.')); 319 libraryPrefix.addAll(libraryJSName.split('.'));
319 } 320 }
320 321
321 String elementJSName; 322 String elementJSName;
322 if (findAnnotation(e, isPublicJSAnnotation) != null) { 323 if (findAnnotation(e, isPublicJSAnnotation) != null) {
323 elementJSName = getAnnotationName(e, isPublicJSAnnotation) ?? ''; 324 elementJSName = getAnnotationName(e, isPublicJSAnnotation) ?? '';
324 } 325 }
326
325 if (e is TopLevelVariableElement && 327 if (e is TopLevelVariableElement &&
326 e.getter != null && 328 e.getter != null &&
327 (e.getter.isExternal || 329 (e.getter.isExternal ||
328 findAnnotation(e.getter, isPublicJSAnnotation) != null)) { 330 findAnnotation(e.getter, isPublicJSAnnotation) != null)) {
329 elementJSName = getAnnotationName(e.getter, isPublicJSAnnotation) ?? ''; 331 elementJSName = getAnnotationName(e.getter, isPublicJSAnnotation) ?? '';
330 } 332 }
331 if (elementJSName == null) return null; 333 if (elementJSName == null) return null;
332 334
333 var elementJSParts = <String>[]; 335 var elementJSParts = <String>[];
334 if (elementJSName.isNotEmpty) { 336 if (elementJSName.isNotEmpty) {
(...skipping 2363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2698 2700
2699 var name = element.name; 2701 var name = element.name;
2700 2702
2701 // Unqualified class member. This could mean implicit-this, or implicit 2703 // Unqualified class member. This could mean implicit-this, or implicit
2702 // call to a static from the same class. 2704 // call to a static from the same class.
2703 if (element is ClassMemberElement && element is! ConstructorElement) { 2705 if (element is ClassMemberElement && element is! ConstructorElement) {
2704 bool isStatic = element.isStatic; 2706 bool isStatic = element.isStatic;
2705 var type = element.enclosingElement.type; 2707 var type = element.enclosingElement.type;
2706 var member = _emitMemberName(name, isStatic: isStatic, type: type); 2708 var member = _emitMemberName(name, isStatic: isStatic, type: type);
2707 2709
2708 // For static methods, we add the raw type name, without generics or
2709 // library prefix. We don't need those because static calls can't use
2710 // the generic type.
2711 if (isStatic) { 2710 if (isStatic) {
2712 var dynType = _emitType(fillDynamicTypeArgs(type)); 2711 var dynType = _emitStaticAccess(type);
2713 return new JS.PropertyAccess(dynType, member); 2712 return new JS.PropertyAccess(dynType, member);
2714 } 2713 }
2715 2714
2716 // For instance members, we add implicit-this. 2715 // For instance members, we add implicit-this.
2717 // For method tear-offs, we ensure it's a bound method. 2716 // For method tear-offs, we ensure it's a bound method.
2718 var tearOff = element is MethodElement && !inInvocationContext(node); 2717 var tearOff = element is MethodElement && !inInvocationContext(node);
2719 if (tearOff) return _callHelper('bind(this, #)', member); 2718 if (tearOff) return _callHelper('bind(this, #)', member);
2720 return js.call('this.#', member); 2719 return js.call('this.#', member);
2721 } 2720 }
2722 2721
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2901 ]; 2900 ];
2902 } else { 2901 } else {
2903 typeParts = [ 2902 typeParts = [
2904 js.call('(#) => {#; return #;}', [tf, names, parts]) 2903 js.call('(#) => {#; return #;}', [tf, names, parts])
2905 ]; 2904 ];
2906 } 2905 }
2907 } 2906 }
2908 return typeParts; 2907 return typeParts;
2909 } 2908 }
2910 2909
2910 /// Emits an expression that lets you access statics on a [type] from code.
2911 ///
2912 /// If [nameType] is true, then the type will be named. In addition,
2913 /// if [hoistType] is true, then the named type will be hoisted.
2914 JS.Expression _emitConstructorAccess(DartType type,
2915 {bool nameType: true, bool hoistType: true}) {
2916 return _emitJSInterop(type.element) ??
2917 _emitType(type, nameType: nameType, hoistType: hoistType);
2918 }
2919
2920 /// Emits an expression that lets you access statics on a [type] from code.
2921 JS.Expression _emitStaticAccess(DartType type) {
2922 // Make sure we aren't attempting to emit a static access path to a type
2923 // that does not have a valid static access path.
2924 assert(!type.isVoid &&
2925 !type.isDynamic &&
2926 !type.isBottom &&
2927 type is! TypeParameterType);
2928
2929 // For statics, we add the raw type name, without generics or
2930 // library prefix. We don't need those because static calls can't use
2931 // the generic type.
2932 type = fillDynamicTypeArgs(type);
2933 var element = type.element;
2934 _declareBeforeUse(element);
2935
2936 var interop = _emitJSInterop(element);
2937 if (interop != null) return interop;
2938
2939 assert(type.name != '' && type.name != null);
2940
2941 return _emitTopLevelNameNoInterop(element);
2942 }
2943
2911 /// Emits a Dart [type] into code. 2944 /// Emits a Dart [type] into code.
2912 /// 2945 ///
2913 /// If [lowerTypedef] is set, a typedef will be expanded as if it were a 2946 /// If [lowerTypedef] is set, a typedef will be expanded as if it were a
2914 /// function type. Similarly if [lowerGeneric] is set, the `List$()` form 2947 /// function type. Similarly if [lowerGeneric] is set, the `List$()` form
2915 /// will be used instead of `List`. These flags are used when generating 2948 /// will be used instead of `List`. These flags are used when generating
2916 /// the definitions for typedefs and generic types, respectively. 2949 /// the definitions for typedefs and generic types, respectively.
2917 /// 2950 ///
2918 /// If [subClass] is set, then we are setting the base class for the given 2951 /// If [subClass] is set, then we are setting the base class for the given
2919 /// class and should emit the given [className], which will already be 2952 /// class and should emit the given [className], which will already be
2920 /// defined. 2953 /// defined.
2921 /// 2954 ///
2922 /// If [nameType] is true, then the type will be named. In addition, 2955 /// If [nameType] is true, then the type will be named. In addition,
2923 /// if [hoistType] is true, then the named type will be hoisted. 2956 /// if [hoistType] is true, then the named type will be hoisted.
2924 JS.Expression _emitType(DartType type, 2957 JS.Expression _emitType(DartType type,
2925 {bool lowerTypedef: false, 2958 {bool lowerTypedef: false,
2926 bool lowerGeneric: false, 2959 bool lowerGeneric: false,
2927 bool nameType: true, 2960 bool nameType: true,
2928 bool hoistType: true, 2961 bool hoistType: true,
2929 ClassElement subClass, 2962 ClassElement subClass,
2930 JS.Expression className}) { 2963 JS.Expression className}) {
2931 // The void and dynamic types are not defined in core. 2964 // The void and dynamic types are not defined in core.
2932 if (type.isVoid) { 2965 if (type.isVoid) {
2933 return _callHelper('void'); 2966 return _callHelper('void');
2934 } else if (type.isDynamic) { 2967 } else if (type.isDynamic) {
2935 return _callHelper('dynamic'); 2968 return _callHelper('dynamic');
2936 } else if (type.isBottom) { 2969 } else if (type.isBottom) {
2937 return _callHelper('bottom'); 2970 return _callHelper('bottom');
2938 } 2971 }
2939 2972
2940 _declareBeforeUse(type.element); 2973 var element = type.element;
2974 _declareBeforeUse(element);
2975
2976 var interop = _emitJSInterop(element);
2977 // Type parameters don't matter as JS interop types cannot be reified.
2978 // We have to use lazy JS types because until we have proper module
2979 // loading for JS libraries bundled with Dart libraries, we will sometimes
2980 // need to load Dart libraries before the corresponding JS libraries are
2981 // actually loaded.
2982 // Given a JS type such as:
2983 // @JS('google.maps.Location')
2984 // class Location { ... }
2985 // We can't emit a reference to MyType because the JS library that defines
2986 // it may be loaded after our code. So for now, we use a special lazy type
2987 // object to represent MyType.
2988 // Anonymous JS types do not have a corresponding concrete JS type so we
2989 // have to use a helper to define them.
2990 if (interop != null) {
2991 if (_isObjectLiteral(element)) {
2992 return _callHelper(
2993 'lazyAnonymousJSType(#)', js.string(element.displayName));
2994 } else {
2995 return _callHelper('lazyJSType(() => #, #)',
2996 [interop, js.string(_getJSName(element).join('.'))]);
2997 }
2998 }
2941 2999
2942 // TODO(jmesserly): like constants, should we hoist function types out of 3000 // TODO(jmesserly): like constants, should we hoist function types out of
2943 // methods? Similar issue with generic types. For all of these, we may want 3001 // methods? Similar issue with generic types. For all of these, we may want
2944 // to canonicalize them too, at least when inside the same library. 3002 // to canonicalize them too, at least when inside the same library.
2945 var name = type.name; 3003 var name = type.name;
2946 var element = type.element;
2947 if (name == '' || name == null || lowerTypedef) { 3004 if (name == '' || name == null || lowerTypedef) {
2948 // TODO(jmesserly): should we change how typedefs work? They currently 3005 // TODO(jmesserly): should we change how typedefs work? They currently
2949 // go through use similar logic as generic classes. This makes them 3006 // go through use similar logic as generic classes. This makes them
2950 // different from universal function types. 3007 // different from universal function types.
2951 return _emitFunctionType(type as FunctionType, 3008 return _emitFunctionType(type as FunctionType,
2952 lowerTypedef: lowerTypedef, nameType: nameType, hoistType: hoistType); 3009 lowerTypedef: lowerTypedef, nameType: nameType, hoistType: hoistType);
2953 } 3010 }
2954 3011
2955 if (type is TypeParameterType) { 3012 if (type is TypeParameterType) {
2956 _typeParamInConst?.add(type); 3013 _typeParamInConst?.add(type);
2957 return new JS.Identifier(name); 3014 return new JS.Identifier(name);
2958 } 3015 }
2959 3016
2960 if (type == subClass?.type) { 3017 if (type == subClass?.type) return className;
2961 return className;
2962 }
2963 3018
2964 if (type is ParameterizedType) { 3019 if (type is ParameterizedType) {
2965 var args = type.typeArguments; 3020 var args = type.typeArguments;
2966 Iterable jsArgs = null; 3021 Iterable jsArgs = null;
2967 if (args.any((a) => !a.isDynamic)) { 3022 if (args.any((a) => !a.isDynamic)) {
2968 jsArgs = args.map((x) => _emitType(x, 3023 jsArgs = args.map((x) => _emitType(x,
2969 nameType: nameType, 3024 nameType: nameType,
2970 hoistType: hoistType, 3025 hoistType: hoistType,
2971 subClass: subClass, 3026 subClass: subClass,
2972 className: className)); 3027 className: className));
2973 } else if (lowerGeneric || element == subClass) { 3028 } else if (lowerGeneric || element == subClass) {
2974 jsArgs = []; 3029 jsArgs = [];
2975 } 3030 }
2976 if (jsArgs != null) { 3031 if (jsArgs != null) {
2977 var genericName = _emitTopLevelName(element, suffix: '\$'); 3032 var genericName = _emitTopLevelName(element, suffix: '\$');
2978 var typeRep = js.call('#(#)', [genericName, jsArgs]); 3033 var typeRep = js.call('#(#)', [genericName, jsArgs]);
2979 return nameType 3034 return nameType
2980 ? _typeTable.nameType(type, typeRep, hoistType: hoistType) 3035 ? _typeTable.nameType(type, typeRep, hoistType: hoistType)
2981 : typeRep; 3036 : typeRep;
2982 } 3037 }
2983 } 3038 }
2984 3039
2985 return _emitTopLevelName(element); 3040 return _emitTopLevelNameNoInterop(element);
2986 } 3041 }
2987 3042
2988 JS.PropertyAccess _emitTopLevelName(Element e, {String suffix: ''}) { 3043 JS.PropertyAccess _emitTopLevelName(Element e, {String suffix: ''}) {
2989 var interop = _emitJSInterop(e); 3044 var interop = _emitJSInterop(e);
2990 if (interop != null) return interop; 3045 if (interop != null) return interop;
3046 return _emitTopLevelNameNoInterop(e, suffix: suffix);
3047 }
3048
3049 JS.PropertyAccess _emitTopLevelNameNoInterop(Element e, {String suffix: ''}) {
2991 String name = getJSExportName(e) + suffix; 3050 String name = getJSExportName(e) + suffix;
2992 return new JS.PropertyAccess( 3051 return new JS.PropertyAccess(
2993 emitLibraryName(e.library), _propertyName(name)); 3052 emitLibraryName(e.library), _propertyName(name));
2994 } 3053 }
2995 3054
2996 @override 3055 @override
2997 JS.Expression visitAssignmentExpression(AssignmentExpression node) { 3056 JS.Expression visitAssignmentExpression(AssignmentExpression node) {
2998 var left = node.leftHandSide; 3057 var left = node.leftHandSide;
2999 var right = node.rightHandSide; 3058 var right = node.rightHandSide;
3000 if (node.operator.type == TokenType.EQ) return _emitSet(left, right); 3059 if (node.operator.type == TokenType.EQ) return _emitSet(left, right);
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
3204 } 3263 }
3205 3264
3206 /// Emits assignment to a static field element or property. 3265 /// Emits assignment to a static field element or property.
3207 JS.Expression _emitSetStaticProperty( 3266 JS.Expression _emitSetStaticProperty(
3208 Expression lhs, Element element, Expression rhs) { 3267 Expression lhs, Element element, Expression rhs) {
3209 // For static methods, we add the raw type name, without generics or 3268 // For static methods, we add the raw type name, without generics or
3210 // library prefix. We don't need those because static calls can't use 3269 // library prefix. We don't need those because static calls can't use
3211 // the generic type. 3270 // the generic type.
3212 ClassElement classElement = element.enclosingElement; 3271 ClassElement classElement = element.enclosingElement;
3213 var type = classElement.type; 3272 var type = classElement.type;
3214 var dynType = _emitType(fillDynamicTypeArgs(type)); 3273 var dynType = _emitStaticAccess(type);
3215 var member = _emitMemberName(element.name, isStatic: true, type: type); 3274 var member = _emitMemberName(element.name, isStatic: true, type: type);
3216 return _visit(rhs).toAssignExpression( 3275 return _visit(rhs).toAssignExpression(
3217 annotate(new JS.PropertyAccess(dynType, member), lhs)); 3276 annotate(new JS.PropertyAccess(dynType, member), lhs));
3218 } 3277 }
3219 3278
3220 /// Emits an assignment to the [element] property of instance referenced by 3279 /// Emits an assignment to the [element] property of instance referenced by
3221 /// [jsTarget]. 3280 /// [jsTarget].
3222 JS.Expression _emitWriteInstanceProperty(Expression lhs, 3281 JS.Expression _emitWriteInstanceProperty(Expression lhs,
3223 JS.Expression jsTarget, Element element, JS.Expression value) { 3282 JS.Expression jsTarget, Element element, JS.Expression value) {
3224 String memberName = element.name; 3283 String memberName = element.name;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3355 JS.Expression _getSuperHelperFor(String name, JS.Expression forwardedCall, 3414 JS.Expression _getSuperHelperFor(String name, JS.Expression forwardedCall,
3356 List<JS.Expression> helperArgs) { 3415 List<JS.Expression> helperArgs) {
3357 var helperMethod = 3416 var helperMethod =
3358 new JS.Fun(helperArgs, new JS.Block([new JS.Return(forwardedCall)])); 3417 new JS.Fun(helperArgs, new JS.Block([new JS.Return(forwardedCall)]));
3359 var helperMethodName = new JS.TemporaryId('super\$$name'); 3418 var helperMethodName = new JS.TemporaryId('super\$$name');
3360 _superHelperSymbols.add(helperMethodName); 3419 _superHelperSymbols.add(helperMethodName);
3361 _superHelpers.add(new JS.Method(helperMethodName, helperMethod)); 3420 _superHelpers.add(new JS.Method(helperMethodName, helperMethod));
3362 return helperMethodName; 3421 return helperMethodName;
3363 } 3422 }
3364 3423
3424 JS.Expression _emitTarget(Expression target, Element element, bool isStatic) {
3425 if (isStatic) {
3426 if (element is ConstructorElement) {
3427 return _emitConstructorAccess(element.enclosingElement.type);
3428 }
3429 if (element is ExecutableElement) {
3430 return _emitStaticAccess(
3431 (element.enclosingElement as ClassElement).type);
3432 }
3433 }
3434 return _visit(target);
3435 }
3436
3365 /// Emits a (possibly generic) instance method call. 3437 /// Emits a (possibly generic) instance method call.
3366 JS.Expression _emitMethodCallInternal( 3438 JS.Expression _emitMethodCallInternal(
3367 Expression target, 3439 Expression target,
3368 MethodInvocation node, 3440 MethodInvocation node,
3369 List<JS.Expression> args, 3441 List<JS.Expression> args,
3370 List<JS.Expression> typeArgs) { 3442 List<JS.Expression> typeArgs) {
3371 var type = getStaticType(target); 3443 var type = getStaticType(target);
3372 var name = node.methodName.name; 3444 var name = node.methodName.name;
3373 var element = node.methodName.staticElement; 3445 var element = node.methodName.staticElement;
3374 bool isStatic = element is ExecutableElement && element.isStatic; 3446 bool isStatic = element is ExecutableElement && element.isStatic;
3375 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); 3447 var memberName = _emitMemberName(name, type: type, isStatic: isStatic);
3376 3448
3377 JS.Expression jsTarget = _visit(target); 3449 JS.Expression jsTarget = _emitTarget(target, element, isStatic);
3378 if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) { 3450 if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) {
3379 if (_inWhitelistCode(target)) { 3451 if (_inWhitelistCode(target)) {
3380 var vars = <JS.MetaLetVariable, JS.Expression>{}; 3452 var vars = <JS.MetaLetVariable, JS.Expression>{};
3381 var l = _visit(_bindValue(vars, 'l', target)); 3453 var l = _visit(_bindValue(vars, 'l', target));
3382 jsTarget = new JS.MetaLet(vars, [ 3454 jsTarget = new JS.MetaLet(vars, [
3383 js.call('(#[(#[#._extensionType]) ? #[#] : #]).bind(#)', [ 3455 js.call('(#[(#[#._extensionType]) ? #[#] : #]).bind(#)', [
3384 l, 3456 l,
3385 l, 3457 l,
3386 _runtimeModule, 3458 _runtimeModule,
3387 _extensionSymbolsModule, 3459 _extensionSymbolsModule,
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
3892 : parent.getSetter(element.name); 3964 : parent.getSetter(element.name);
3893 } 3965 }
3894 return null; 3966 return null;
3895 } 3967 }
3896 3968
3897 JS.Expression _emitConstructorName( 3969 JS.Expression _emitConstructorName(
3898 ConstructorElement element, DartType type, SimpleIdentifier name) { 3970 ConstructorElement element, DartType type, SimpleIdentifier name) {
3899 var classElem = element.enclosingElement; 3971 var classElem = element.enclosingElement;
3900 var interop = _emitJSInterop(classElem); 3972 var interop = _emitJSInterop(classElem);
3901 if (interop != null) return interop; 3973 if (interop != null) return interop;
3902 var typeName = _emitType(type); 3974 var typeName = _emitConstructorAccess(type);
3903 if (name != null || element.isFactory) { 3975 if (name != null || element.isFactory) {
3904 var namedCtor = _constructorName(element); 3976 var namedCtor = _constructorName(element);
3905 return new JS.PropertyAccess(typeName, namedCtor); 3977 return new JS.PropertyAccess(typeName, namedCtor);
3906 } 3978 }
3907 return typeName; 3979 return typeName;
3908 } 3980 }
3909 3981
3910 @override 3982 @override
3911 visitConstructorName(ConstructorName node) { 3983 visitConstructorName(ConstructorName node) {
3912 return _emitConstructorName(node.staticElement, node.type.type, node.name); 3984 return _emitConstructorName(node.staticElement, node.type.type, node.name);
3913 } 3985 }
3914 3986
3915 JS.Expression _emitInstanceCreationExpression( 3987 JS.Expression _emitInstanceCreationExpression(
3916 ConstructorElement element, 3988 ConstructorElement element,
3917 DartType type, 3989 DartType type,
3918 SimpleIdentifier name, 3990 SimpleIdentifier name,
3919 ArgumentList argumentList, 3991 ArgumentList argumentList,
3920 bool isConst) { 3992 bool isConst) {
3921 JS.Expression emitNew() { 3993 JS.Expression emitNew() {
3922 JS.Expression ctor; 3994 JS.Expression ctor;
3923 bool isFactory = false; 3995 bool isFactory = false;
3924 bool isNative = false; 3996 bool isNative = false;
3925 if (element == null) { 3997 if (element == null) {
3926 // TODO(jmesserly): this only happens if we had a static error. 3998 // TODO(jmesserly): this only happens if we had a static error.
3927 // Should we generate a throw instead? 3999 // Should we generate a throw instead?
3928 ctor = _emitType(type, 4000 ctor = _emitConstructorAccess(type,
3929 nameType: options.hoistInstanceCreation, 4001 nameType: options.hoistInstanceCreation,
3930 hoistType: options.hoistInstanceCreation); 4002 hoistType: options.hoistInstanceCreation);
3931 if (name != null) { 4003 if (name != null) {
3932 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name)); 4004 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name));
3933 } 4005 }
3934 } else { 4006 } else {
3935 ctor = _emitConstructorName(element, type, name); 4007 ctor = _emitConstructorName(element, type, name);
3936 isFactory = element.isFactory; 4008 isFactory = element.isFactory;
3937 var classElem = element.enclosingElement; 4009 var classElem = element.enclosingElement;
3938 isNative = _isJSNative(classElem); 4010 isNative = _isJSNative(classElem);
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
4742 var l = _visit(_bindValue(vars, 'l', target)); 4814 var l = _visit(_bindValue(vars, 'l', target));
4743 return new JS.MetaLet(vars, [ 4815 return new JS.MetaLet(vars, [
4744 js.call('(#[#._extensionType]) ? #[#[#]] : #.#', 4816 js.call('(#[#._extensionType]) ? #[#[#]] : #.#',
4745 [l, _runtimeModule, l, _extensionSymbolsModule, name, l, name]) 4817 [l, _runtimeModule, l, _extensionSymbolsModule, name, l, name])
4746 ]); 4818 ]);
4747 } 4819 }
4748 return _callHelper('#(#, #)', 4820 return _callHelper('#(#, #)',
4749 [_emitDynamicOperationName('dload'), _visit(target), name]); 4821 [_emitDynamicOperationName('dload'), _visit(target), name]);
4750 } 4822 }
4751 4823
4752 var jsTarget = _visit(target); 4824 var jsTarget = _emitTarget(target, member, isStatic);
4753 bool isSuper = jsTarget is JS.Super; 4825 bool isSuper = jsTarget is JS.Super;
4754 4826
4755 if (isSuper && member is FieldElement && !member.isSynthetic) { 4827 if (isSuper && member is FieldElement && !member.isSynthetic) {
4756 // If super.x is actually a field, then x is an instance property since 4828 // If super.x is actually a field, then x is an instance property since
4757 // subclasses cannot override x. 4829 // subclasses cannot override x.
4758 jsTarget = new JS.This(); 4830 jsTarget = new JS.This();
4759 } 4831 }
4760 4832
4761 JS.Expression result; 4833 JS.Expression result;
4762 if (member != null && member is MethodElement && !isStatic) { 4834 if (member != null && member is MethodElement && !isStatic) {
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
5116 5188
5117 @override 5189 @override
5118 visitNullLiteral(NullLiteral node) => new JS.LiteralNull(); 5190 visitNullLiteral(NullLiteral node) => new JS.LiteralNull();
5119 5191
5120 @override 5192 @override
5121 visitSymbolLiteral(SymbolLiteral node) { 5193 visitSymbolLiteral(SymbolLiteral node) {
5122 JS.Expression emitSymbol() { 5194 JS.Expression emitSymbol() {
5123 // TODO(vsm): When we canonicalize, we need to treat private symbols 5195 // TODO(vsm): When we canonicalize, we need to treat private symbols
5124 // correctly. 5196 // correctly.
5125 var name = js.string(node.components.join('.'), "'"); 5197 var name = js.string(node.components.join('.'), "'");
5126 return js.call('#.new(#)', [_emitType(types.symbolType), name]); 5198 return js
5199 .call('#.new(#)', [_emitConstructorAccess(types.symbolType), name]);
5127 } 5200 }
5128 5201
5129 return _emitConst(emitSymbol); 5202 return _emitConst(emitSymbol);
5130 } 5203 }
5131 5204
5132 @override 5205 @override
5133 visitListLiteral(ListLiteral node) { 5206 visitListLiteral(ListLiteral node) {
5134 var isConst = node.constKeyword != null; 5207 var isConst = node.constKeyword != null;
5135 JS.Expression emitList() { 5208 JS.Expression emitList() {
5136 JS.Expression list = new JS.ArrayInitializer( 5209 JS.Expression list = new JS.ArrayInitializer(
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
5644 var targetIdentifier = target as SimpleIdentifier; 5717 var targetIdentifier = target as SimpleIdentifier;
5645 5718
5646 if (targetIdentifier.staticElement is! PrefixElement) return false; 5719 if (targetIdentifier.staticElement is! PrefixElement) return false;
5647 var prefix = targetIdentifier.staticElement as PrefixElement; 5720 var prefix = targetIdentifier.staticElement as PrefixElement;
5648 5721
5649 // The library the prefix is referring to must come from a deferred import. 5722 // The library the prefix is referring to must come from a deferred import.
5650 var containingLibrary = (target.root as CompilationUnit).element.library; 5723 var containingLibrary = (target.root as CompilationUnit).element.library;
5651 var imports = containingLibrary.getImportsWithPrefix(prefix); 5724 var imports = containingLibrary.getImportsWithPrefix(prefix);
5652 return imports.length == 1 && imports[0].isDeferred; 5725 return imports.length == 1 && imports[0].isDeferred;
5653 } 5726 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/lib/sdk/ddc_sdk.sum ('k') | pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_lazy_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698