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

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

Issue 3009623002: fix list_test for strong mode, and fix DDC List constructors (Closed)
Patch Set: Created 3 years, 3 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 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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 143
144 final ClassElement boolClass; 144 final ClassElement boolClass;
145 final ClassElement intClass; 145 final ClassElement intClass;
146 final ClassElement interceptorClass; 146 final ClassElement interceptorClass;
147 final ClassElement nullClass; 147 final ClassElement nullClass;
148 final ClassElement numClass; 148 final ClassElement numClass;
149 final ClassElement objectClass; 149 final ClassElement objectClass;
150 final ClassElement stringClass; 150 final ClassElement stringClass;
151 final ClassElement functionClass; 151 final ClassElement functionClass;
152 final ClassElement privateSymbolClass; 152 final ClassElement privateSymbolClass;
153 final PropertyAccessorElement _undefinedConstant;
153 154
154 ConstFieldVisitor _constants; 155 ConstFieldVisitor _constants;
155 156
156 /// The current function body being compiled. 157 /// The current function body being compiled.
157 FunctionBody _currentFunction; 158 FunctionBody _currentFunction;
158 159
159 HashMap<TypeDefiningElement, AstNode> _declarationNodes; 160 HashMap<TypeDefiningElement, AstNode> _declarationNodes;
160 161
161 /// The stack of currently emitting elements, if generating top-level code 162 /// The stack of currently emitting elements, if generating top-level code
162 /// for them. This is not used when inside method bodies, because order does 163 /// for them. This is not used when inside method bodies, because order does
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 dartCoreLibrary = _getLibrary(c, 'dart:core'), 217 dartCoreLibrary = _getLibrary(c, 'dart:core'),
217 boolClass = _getLibrary(c, 'dart:core').getType('bool'), 218 boolClass = _getLibrary(c, 'dart:core').getType('bool'),
218 intClass = _getLibrary(c, 'dart:core').getType('int'), 219 intClass = _getLibrary(c, 'dart:core').getType('int'),
219 numClass = _getLibrary(c, 'dart:core').getType('num'), 220 numClass = _getLibrary(c, 'dart:core').getType('num'),
220 nullClass = _getLibrary(c, 'dart:core').getType('Null'), 221 nullClass = _getLibrary(c, 'dart:core').getType('Null'),
221 objectClass = _getLibrary(c, 'dart:core').getType('Object'), 222 objectClass = _getLibrary(c, 'dart:core').getType('Object'),
222 stringClass = _getLibrary(c, 'dart:core').getType('String'), 223 stringClass = _getLibrary(c, 'dart:core').getType('String'),
223 functionClass = _getLibrary(c, 'dart:core').getType('Function'), 224 functionClass = _getLibrary(c, 'dart:core').getType('Function'),
224 privateSymbolClass = 225 privateSymbolClass =
225 _getLibrary(c, 'dart:_internal').getType('PrivateSymbol'), 226 _getLibrary(c, 'dart:_internal').getType('PrivateSymbol'),
226 dartJSLibrary = _getLibrary(c, 'dart:js') { 227 dartJSLibrary = _getLibrary(c, 'dart:js'),
228 _undefinedConstant =
229 _getLibrary(c, 'dart:_runtime').publicNamespace.get('undefined') {
230 assert(_undefinedConstant != null);
227 typeRep = new JSTypeRep(rules, types); 231 typeRep = new JSTypeRep(rules, types);
228 } 232 }
229 233
230 Element get currentElement => _currentElements.last; 234 Element get currentElement => _currentElements.last;
231 235
232 LibraryElement get currentLibrary => currentElement.library; 236 LibraryElement get currentLibrary => currentElement.library;
233 237
234 /// The main entry point to JavaScript code generation. 238 /// The main entry point to JavaScript code generation.
235 /// 239 ///
236 /// Takes the metadata for the build unit, as well as resolved trees and 240 /// Takes the metadata for the build unit, as well as resolved trees and
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 // per-compilation-unit state. Declarations can be visited out of order, 590 // per-compilation-unit state. Declarations can be visited out of order,
587 // this is only to catch things that haven't been emitted yet. 591 // this is only to catch things that haven't been emitted yet.
588 // 592 //
589 // See _emitTypeDeclaration. 593 // See _emitTypeDeclaration.
590 _currentElements.add(unit.element); 594 _currentElements.add(unit.element);
591 var isInternalSdk = isSdkInternalRuntime(currentLibrary); 595 var isInternalSdk = isSdkInternalRuntime(currentLibrary);
592 List<VariableDeclaration> fields; 596 List<VariableDeclaration> fields;
593 for (var declaration in unit.declarations) { 597 for (var declaration in unit.declarations) {
594 if (declaration is TopLevelVariableDeclaration) { 598 if (declaration is TopLevelVariableDeclaration) {
595 inferNullableTypes(declaration); 599 inferNullableTypes(declaration);
596 if (isInternalSdk && declaration.variables.isFinal) { 600 if (isInternalSdk &&
601 (declaration.variables.isFinal || declaration.variables.isConst)) {
597 _emitInternalSdkFields(declaration.variables.variables); 602 _emitInternalSdkFields(declaration.variables.variables);
598 } else { 603 } else {
599 (fields ??= []).addAll(declaration.variables.variables); 604 (fields ??= []).addAll(declaration.variables.variables);
600 } 605 }
601 continue; 606 continue;
602 } 607 }
603 608
604 if (fields != null) { 609 if (fields != null) {
605 _emitTopLevelFields(fields); 610 _emitTopLevelFields(fields);
606 fields = null; 611 fields = null;
(...skipping 1797 matching lines...) Expand 10 before | Expand all | Expand 10 after
2404 // than always when we visit the function body, so we control it explicitly. 2409 // than always when we visit the function body, so we control it explicitly.
2405 if (node is ConstructorDeclaration != constructor) return null; 2410 if (node is ConstructorDeclaration != constructor) return null;
2406 2411
2407 var parameters = _parametersOf(node); 2412 var parameters = _parametersOf(node);
2408 if (parameters == null) return null; 2413 if (parameters == null) return null;
2409 2414
2410 var body = <JS.Statement>[]; 2415 var body = <JS.Statement>[];
2411 for (var param in parameters.parameters) { 2416 for (var param in parameters.parameters) {
2412 var jsParam = _emitSimpleIdentifier(param.identifier); 2417 var jsParam = _emitSimpleIdentifier(param.identifier);
2413 2418
2414 if (!options.destructureNamedParams) { 2419 if (!options.destructureNamedParams &&
2420 param.kind != ParameterKind.REQUIRED) {
2415 if (param.kind == ParameterKind.NAMED) { 2421 if (param.kind == ParameterKind.NAMED) {
2416 // Parameters will be passed using their real names, not the (possibly 2422 // Parameters will be passed using their real names, not the (possibly
2417 // renamed) local variable. 2423 // renamed) local variable.
2418 var paramName = js.string(param.identifier.name, "'"); 2424 var paramName = js.string(param.identifier.name, "'");
2419 2425 var defaultValue = _defaultParamValue(param);
2420 // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming. 2426 if (defaultValue != null) {
2421 body.add(js.statement('let # = # && # in # ? #.# : #;', [ 2427 // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming.
2422 jsParam, 2428 body.add(js.statement('let # = # && # in # ? #.# : #;', [
2423 namedArgumentTemp, 2429 jsParam,
2424 paramName, 2430 namedArgumentTemp,
2425 namedArgumentTemp, 2431 paramName,
2426 namedArgumentTemp, 2432 namedArgumentTemp,
2427 paramName, 2433 namedArgumentTemp,
2428 _defaultParamValue(param), 2434 paramName,
2429 ])); 2435 defaultValue,
2436 ]));
2437 } else {
2438 body.add(js.statement('let # = # && #.#;', [
2439 jsParam,
2440 namedArgumentTemp,
2441 namedArgumentTemp,
2442 paramName,
2443 ]));
2444 }
2430 } else if (param.kind == ParameterKind.POSITIONAL) { 2445 } else if (param.kind == ParameterKind.POSITIONAL) {
2431 body.add(js.statement('if (# === void 0) # = #;', 2446 var defaultValue = _defaultParamValue(param);
2432 [jsParam, jsParam, _defaultParamValue(param)])); 2447 if (defaultValue != null) {
2448 body.add(js.statement(
2449 'if (# === void 0) # = #;', [jsParam, jsParam, defaultValue]));
2450 }
2433 } 2451 }
2434 } 2452 }
2435 2453
2436 var paramElement = resolutionMap.elementDeclaredByFormalParameter(param); 2454 var paramElement = resolutionMap.elementDeclaredByFormalParameter(param);
2437 if (_isCovariant(paramElement)) { 2455 if (_isCovariant(paramElement)) {
2438 var castType = _emitType(paramElement.type); 2456 var castType = _emitType(paramElement.type);
2439 body.add(js.statement('#._check(#);', [castType, jsParam])); 2457 body.add(js.statement('#._check(#);', [castType, jsParam]));
2440 } 2458 }
2441 if (_annotatedNullCheck(paramElement)) { 2459 if (_annotatedNullCheck(paramElement)) {
2442 body.add(nullParameterCheck(jsParam)); 2460 body.add(nullParameterCheck(jsParam));
2443 } 2461 }
2444 } 2462 }
2445 return body.isEmpty ? null : _statement(body); 2463 return body.isEmpty ? null : _statement(body);
2446 } 2464 }
2447 2465
2448 bool _isCovariant(ParameterElement p) { 2466 bool _isCovariant(ParameterElement p) {
2449 if (p.isCovariant) return true; 2467 if (p.isCovariant) return true;
2450 var covariantParams = _classProperties?.covariantParameters; 2468 var covariantParams = _classProperties?.covariantParameters;
2451 return covariantParams != null && covariantParams.contains(p); 2469 return covariantParams != null && covariantParams.contains(p);
2452 } 2470 }
2453 2471
2454 JS.Expression _defaultParamValue(FormalParameter param) { 2472 JS.Expression _defaultParamValue(FormalParameter param) {
2455 if (param is DefaultFormalParameter && param.defaultValue != null) { 2473 if (param is DefaultFormalParameter && param.defaultValue != null) {
2474 var defaultValue = param.defaultValue;
2475 if (defaultValue is Identifier &&
2476 defaultValue.staticElement == _undefinedConstant) {
2477 return null;
2478 }
2456 return _visit(param.defaultValue); 2479 return _visit(param.defaultValue);
2457 } else { 2480 } else {
2458 return new JS.LiteralNull(); 2481 return new JS.LiteralNull();
2459 } 2482 }
2460 } 2483 }
2461 2484
2462 JS.Fun _emitNativeFunctionBody(MethodDeclaration node) { 2485 JS.Fun _emitNativeFunctionBody(MethodDeclaration node) {
2463 String name = 2486 String name =
2464 getAnnotationName(node.element, isJSAnnotation) ?? node.name.name; 2487 getAnnotationName(node.element, isJSAnnotation) ?? node.name.name;
2465 if (node.isGetter) { 2488 if (node.isGetter) {
(...skipping 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after
3912 } 3935 }
3913 JS.Expression name; 3936 JS.Expression name;
3914 JS.SimpleBindingPattern structure = null; 3937 JS.SimpleBindingPattern structure = null;
3915 String paramName = param.identifier.name; 3938 String paramName = param.identifier.name;
3916 if (JS.invalidVariableName(paramName)) { 3939 if (JS.invalidVariableName(paramName)) {
3917 name = js.string(paramName); 3940 name = js.string(paramName);
3918 structure = new JS.SimpleBindingPattern(_visit(param.identifier)); 3941 structure = new JS.SimpleBindingPattern(_visit(param.identifier));
3919 } else { 3942 } else {
3920 name = _visit(param.identifier); 3943 name = _visit(param.identifier);
3921 } 3944 }
3945
3946 var defaultValue = _defaultParamValue(param);
3922 namedVars.add(new JS.DestructuredVariable( 3947 namedVars.add(new JS.DestructuredVariable(
3923 name: name, 3948 name: name, structure: structure, defaultValue: defaultValue));
3924 structure: structure,
3925 defaultValue: _defaultParamValue(param)));
3926 } else { 3949 } else {
3927 needsOpts = true; 3950 needsOpts = true;
3928 } 3951 }
3929 } else { 3952 } else {
3930 var jsParam = _visit(param); 3953 var jsParam = _visit(param);
3931 result.add(param is DefaultFormalParameter && destructure 3954 var defaultValue = _defaultParamValue(param);
3955 result.add(destructure && defaultValue != null
3932 ? new JS.DestructuredVariable( 3956 ? new JS.DestructuredVariable(
3933 name: jsParam, defaultValue: _defaultParamValue(param)) 3957 name: jsParam, defaultValue: defaultValue)
3934 : jsParam); 3958 : jsParam);
3935 } 3959 }
3936 } 3960 }
3937 3961
3938 if (needsOpts) { 3962 if (needsOpts) {
3939 result.add(namedArgumentTemp); 3963 result.add(namedArgumentTemp);
3940 } else if (namedVars.isNotEmpty) { 3964 } else if (namedVars.isNotEmpty) {
3941 // Note: `var {valueOf} = {}` extracts `Object.prototype.valueOf`, so 3965 // Note: `var {valueOf} = {}` extracts `Object.prototype.valueOf`, so
3942 // in case there are conflicting names we create an object without 3966 // in case there are conflicting names we create an object without
3943 // any prototype. 3967 // any prototype.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
4031 // A normal yield in a sync* 4055 // A normal yield in a sync*
4032 return jsExpr.toYieldStatement(star: star); 4056 return jsExpr.toYieldStatement(star: star);
4033 } 4057 }
4034 4058
4035 @override 4059 @override
4036 JS.Expression visitAwaitExpression(AwaitExpression node) { 4060 JS.Expression visitAwaitExpression(AwaitExpression node) {
4037 return new JS.Yield(_visit(node.expression)); 4061 return new JS.Yield(_visit(node.expression));
4038 } 4062 }
4039 4063
4040 /// This is not used--we emit top-level fields as we are emitting the 4064 /// This is not used--we emit top-level fields as we are emitting the
4041 /// compilation unit, see [_emitCompilationUnit]. 4065 /// compilation unit, see [visitCompilationUnit].
4042 @override 4066 @override
4043 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { 4067 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
4044 assert(false); 4068 assert(false);
4045 } 4069 }
4046 4070
4047 /// This is not used--we emit fields as we are emitting the class, 4071 /// This is not used--we emit fields as we are emitting the class,
4048 /// see [visitClassDeclaration]. 4072 /// see [visitClassDeclaration].
4049 @override 4073 @override
4050 visitFieldDeclaration(FieldDeclaration node) { 4074 visitFieldDeclaration(FieldDeclaration node) {
4051 assert(false); 4075 assert(false);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4092 4116
4093 /// Emits a list of top-level field. 4117 /// Emits a list of top-level field.
4094 void _emitTopLevelFields(List<VariableDeclaration> fields) { 4118 void _emitTopLevelFields(List<VariableDeclaration> fields) {
4095 _moduleItems.add(_emitLazyFields(currentLibrary, fields)); 4119 _moduleItems.add(_emitLazyFields(currentLibrary, fields));
4096 } 4120 }
4097 4121
4098 /// Treat dart:_runtime fields as safe to eagerly evaluate. 4122 /// Treat dart:_runtime fields as safe to eagerly evaluate.
4099 // TODO(jmesserly): it'd be nice to avoid this special case. 4123 // TODO(jmesserly): it'd be nice to avoid this special case.
4100 void _emitInternalSdkFields(List<VariableDeclaration> fields) { 4124 void _emitInternalSdkFields(List<VariableDeclaration> fields) {
4101 for (var field in fields) { 4125 for (var field in fields) {
4126 // Skip our magic undefined constant.
4127 var element = field.element as TopLevelVariableElement;
4128 if (element.getter == _undefinedConstant) continue;
4102 _moduleItems.add(annotate( 4129 _moduleItems.add(annotate(
4103 js.statement('# = #;', 4130 js.statement('# = #;',
4104 [_emitTopLevelName(field.element), _visitInitializer(field)]), 4131 [_emitTopLevelName(field.element), _visitInitializer(field)]),
4105 field, 4132 field,
4106 field.element)); 4133 field.element));
4107 } 4134 }
4108 } 4135 }
4109 4136
4110 JS.Expression _visitInitializer(VariableDeclaration node) { 4137 JS.Expression _visitInitializer(VariableDeclaration node) {
4111 var value = _annotatedNullCheck(node.element) 4138 var value = _annotatedNullCheck(node.element)
(...skipping 1925 matching lines...) Expand 10 before | Expand all | Expand 10 after
6037 // The library the prefix is referring to must come from a deferred import. 6064 // The library the prefix is referring to must come from a deferred import.
6038 var containingLibrary = resolutionMap 6065 var containingLibrary = resolutionMap
6039 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) 6066 .elementDeclaredByCompilationUnit(target.root as CompilationUnit)
6040 .library; 6067 .library;
6041 var imports = containingLibrary.getImportsWithPrefix(prefix); 6068 var imports = containingLibrary.getImportsWithPrefix(prefix);
6042 return imports.length == 1 && imports[0].isDeferred; 6069 return imports.length == 1 && imports[0].isDeferred;
6043 } 6070 }
6044 6071
6045 bool _annotatedNullCheck(Element e) => 6072 bool _annotatedNullCheck(Element e) =>
6046 e != null && findAnnotation(e, isNullCheckAnnotation) != null; 6073 e != null && findAnnotation(e, isNullCheckAnnotation) != null;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698