Skip to content

Commit c591454

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
Inline unprovided optional parameters
Change-Id: I61c82216965062feee8e01ba2533d0ea7c0052ef Reviewed-on: https://dart-review.googlesource.com/c/90700 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Sigmund Cherem <[email protected]>
1 parent 3afc3b5 commit c591454

36 files changed

+1074
-227
lines changed

pkg/compiler/lib/src/inferrer/inferrer_engine.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,8 +1272,11 @@ class KernelTypeSystemStrategy implements TypeSystemStrategy {
12721272

12731273
@override
12741274
void forEachParameter(FunctionEntity function, void f(Local parameter)) {
1275-
forEachOrderedParameter(
1276-
_closedWorld.globalLocalsMap, _closedWorld.elementMap, function, f);
1275+
forEachOrderedParameterAsLocal(
1276+
_closedWorld.globalLocalsMap, _closedWorld.elementMap, function,
1277+
(Local parameter, {bool isElided}) {
1278+
f(parameter);
1279+
});
12771280
}
12781281

12791282
@override

pkg/compiler/lib/src/js_backend/runtime_types.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,6 @@ class RuntimeTypesNeedImpl implements RuntimeTypesNeed {
813813
}
814814

815815
bool methodNeedsTypeArguments(FunctionEntity function) {
816-
if (function.parameterStructure.typeParameters == 0) return false;
817816
return methodsNeedingTypeArguments.contains(function);
818817
}
819818

pkg/compiler/lib/src/js_emitter/model.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -545,8 +545,9 @@ class ParameterStubMethod extends StubMethod {
545545
/// If a stub's member can not be torn off, the [callName] is `null`.
546546
js.Name callName;
547547

548-
ParameterStubMethod(js.Name name, this.callName, js.Expression code)
549-
: super(name, code);
548+
ParameterStubMethod(js.Name name, this.callName, js.Expression code,
549+
{MemberEntity element})
550+
: super(name, code, element: element);
550551

551552
String toString() {
552553
return 'ParameterStubMethod(name=${name.key}, callName=${callName?.key}'

pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ class ParameterStubGenerator {
226226
jsAst.Name name = member.isStatic ? null : _namer.invocationName(selector);
227227
jsAst.Name callName =
228228
(callSelector != null) ? _namer.invocationName(callSelector) : null;
229-
return new ParameterStubMethod(name, callName, function);
229+
return new ParameterStubMethod(name, callName, function, element: member);
230230
}
231231

232232
// We fill the lists depending on possible/invoked selectors. For example,

pkg/compiler/lib/src/js_model/closure.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ abstract class ClosureMemberData implements JMemberData {
10311031
}
10321032

10331033
class ClosureFunctionData extends ClosureMemberData
1034-
with FunctionDataMixin, FunctionNodeMixin
1034+
with FunctionDataTypeVariablesMixin, FunctionDataForEachParameterMixin
10351035
implements FunctionData {
10361036
/// Tag used for identifying serialized [ClosureFunctionData] objects in a
10371037
/// debugging data stream.

pkg/compiler/lib/src/js_model/element_map.dart

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,3 +524,83 @@ ir.Node getFieldInitializer(JsToElementMap elementMap, FieldEntity field) {
524524
}
525525
return node.initializer;
526526
}
527+
528+
void forEachOrderedParameterByFunctionNode(
529+
ir.FunctionNode node,
530+
ParameterStructure parameterStructure,
531+
void f(ir.VariableDeclaration parameter, {bool isOptional, bool isElided}),
532+
{bool useNativeOrdering: false}) {
533+
for (int position = 0;
534+
position < node.positionalParameters.length;
535+
position++) {
536+
ir.VariableDeclaration variable = node.positionalParameters[position];
537+
f(variable,
538+
isOptional: position >= parameterStructure.requiredParameters,
539+
isElided: position >= parameterStructure.positionalParameters);
540+
}
541+
542+
if (node.namedParameters.isEmpty) {
543+
return;
544+
}
545+
546+
List<ir.VariableDeclaration> namedParameters = node.namedParameters.toList();
547+
if (useNativeOrdering) {
548+
namedParameters.sort(nativeOrdering);
549+
} else {
550+
namedParameters.sort(namedOrdering);
551+
}
552+
for (ir.VariableDeclaration variable in namedParameters) {
553+
f(variable,
554+
isOptional: true,
555+
isElided: !parameterStructure.namedParameters.contains(variable.name));
556+
}
557+
}
558+
559+
void forEachOrderedParameter(JsToElementMap elementMap, FunctionEntity function,
560+
void f(ir.VariableDeclaration parameter, {bool isElided})) {
561+
ParameterStructure parameterStructure = function.parameterStructure;
562+
563+
void handleParameter(ir.VariableDeclaration parameter,
564+
{bool isOptional, bool isElided}) {
565+
f(parameter, isElided: isElided);
566+
}
567+
568+
MemberDefinition definition = elementMap.getMemberDefinition(function);
569+
switch (definition.kind) {
570+
case MemberKind.regular:
571+
ir.Node node = definition.node;
572+
if (node is ir.Procedure) {
573+
forEachOrderedParameterByFunctionNode(
574+
node.function, parameterStructure, handleParameter);
575+
return;
576+
}
577+
break;
578+
case MemberKind.constructor:
579+
case MemberKind.constructorBody:
580+
ir.Node node = definition.node;
581+
if (node is ir.Procedure) {
582+
forEachOrderedParameterByFunctionNode(
583+
node.function, parameterStructure, handleParameter);
584+
return;
585+
} else if (node is ir.Constructor) {
586+
forEachOrderedParameterByFunctionNode(
587+
node.function, parameterStructure, handleParameter);
588+
return;
589+
}
590+
break;
591+
case MemberKind.closureCall:
592+
ir.Node node = definition.node;
593+
if (node is ir.FunctionDeclaration) {
594+
forEachOrderedParameterByFunctionNode(
595+
node.function, parameterStructure, handleParameter);
596+
return;
597+
} else if (node is ir.FunctionExpression) {
598+
forEachOrderedParameterByFunctionNode(
599+
node.function, parameterStructure, handleParameter);
600+
return;
601+
}
602+
break;
603+
default:
604+
}
605+
failedAt(function, "Unexpected function definition $definition.");
606+
}

pkg/compiler/lib/src/js_model/element_map_impl.dart

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import '../ordered_typeset.dart';
5050
import '../serialization/serialization.dart';
5151
import '../ssa/type_builder.dart';
5252
import '../universe/call_structure.dart';
53+
import '../universe/member_usage.dart';
5354
import '../universe/selector.dart';
5455

5556
import 'closure.dart';
@@ -144,8 +145,11 @@ class JsKernelToElementMap
144145

145146
Map<IndexedClass, List<IndexedMember>> _injectedClassMembers = {};
146147

147-
JsKernelToElementMap(this.reporter, Environment environment,
148-
KernelToElementMapImpl _elementMap, Iterable<MemberEntity> liveMembers)
148+
JsKernelToElementMap(
149+
this.reporter,
150+
Environment environment,
151+
KernelToElementMapImpl _elementMap,
152+
Map<MemberEntity, MemberUsage> liveMemberUsage)
149153
: this.options = _elementMap.options {
150154
_elementEnvironment = new JsElementEnvironment(this);
151155
_commonElements = new CommonElementsImpl(_elementEnvironment);
@@ -161,7 +165,7 @@ class JsKernelToElementMap
161165
KLibraryEnv oldEnv = _elementMap.libraries.getEnv(oldLibrary);
162166
KLibraryData data = _elementMap.libraries.getData(oldLibrary);
163167
IndexedLibrary newLibrary = convertLibrary(oldLibrary);
164-
JLibraryEnv newEnv = oldEnv.convert(_elementMap, liveMembers);
168+
JLibraryEnv newEnv = oldEnv.convert(_elementMap, liveMemberUsage);
165169
libraryMap[oldEnv.library] =
166170
libraries.register<IndexedLibrary, JLibraryData, JLibraryEnv>(
167171
newLibrary, data.convert(), newEnv);
@@ -178,7 +182,7 @@ class JsKernelToElementMap
178182
IndexedLibrary oldLibrary = oldClass.library;
179183
LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
180184
IndexedClass newClass = convertClass(newLibrary, oldClass);
181-
JClassEnv newEnv = env.convert(_elementMap, liveMembers);
185+
JClassEnv newEnv = env.convert(_elementMap, liveMemberUsage);
182186
classMap[env.cls] = classes.register(newClass, data.convert(), newEnv);
183187
assert(newClass.classIndex == oldClass.classIndex);
184188
libraries.getEnv(newClass.library).registerClass(newClass.name, newEnv);
@@ -206,7 +210,8 @@ class JsKernelToElementMap
206210
memberIndex < _elementMap.members.length;
207211
memberIndex++) {
208212
IndexedMember oldMember = _elementMap.members.getEntity(memberIndex);
209-
if (!liveMembers.contains(oldMember)) {
213+
MemberUsage memberUsage = liveMemberUsage[oldMember];
214+
if (memberUsage == null) {
210215
members.skipIndex(oldMember.memberIndex);
211216
continue;
212217
}
@@ -216,9 +221,14 @@ class JsKernelToElementMap
216221
LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
217222
ClassEntity newClass =
218223
oldClass != null ? classes.getEntity(oldClass.classIndex) : null;
219-
IndexedMember newMember = convertMember(newLibrary, newClass, oldMember);
224+
IndexedMember newMember =
225+
convertMember(newLibrary, newClass, oldMember, memberUsage);
220226
members.register(newMember, data.convert());
221-
assert(newMember.memberIndex == oldMember.memberIndex);
227+
assert(
228+
newMember.memberIndex == oldMember.memberIndex,
229+
"Member index mismatch: "
230+
"Old member $oldMember has index ${oldMember.memberIndex} "
231+
"whereas new member $newMember has index ${newMember.memberIndex}");
222232
if (newMember.isField) {
223233
fieldMap[data.node] = newMember;
224234
} else if (newMember.isConstructor) {
@@ -1120,20 +1130,6 @@ class JsKernelToElementMap
11201130
argumentCount, namedArguments, arguments.types.length);
11211131
}
11221132

1123-
ParameterStructure getParameterStructure(ir.FunctionNode node,
1124-
// TODO(johnniwinther): Remove this when type arguments are passed to
1125-
// constructors like calling a generic method.
1126-
{bool includeTypeParameters: true}) {
1127-
// TODO(johnniwinther): Cache the computed function type.
1128-
int requiredParameters = node.requiredParameterCount;
1129-
int positionalParameters = node.positionalParameters.length;
1130-
int typeParameters = node.typeParameters.length;
1131-
List<String> namedParameters =
1132-
node.namedParameters.map((p) => p.name).toList()..sort();
1133-
return new ParameterStructure(requiredParameters, positionalParameters,
1134-
namedParameters, includeTypeParameters ? typeParameters : 0);
1135-
}
1136-
11371133
Selector getSelector(ir.Expression node) {
11381134
// TODO(efortuna): This is screaming for a common interface between
11391135
// PropertyGet and SuperPropertyGet (and same for *Get). Talk to kernel
@@ -1480,8 +1476,9 @@ class JsKernelToElementMap
14801476
isFromEnvironmentConstructor: isFromEnvironmentConstructor);
14811477
}
14821478

1483-
JConstructorBody createConstructorBody(ConstructorEntity constructor) {
1484-
return new JConstructorBody(constructor);
1479+
JConstructorBody createConstructorBody(
1480+
ConstructorEntity constructor, ParameterStructure parameterStructure) {
1481+
return new JConstructorBody(constructor, parameterStructure);
14851482
}
14861483

14871484
JGeneratorBody createGeneratorBody(
@@ -1536,8 +1533,8 @@ class JsKernelToElementMap
15361533
return createTypedef(library, typedef.name);
15371534
}
15381535

1539-
MemberEntity convertMember(
1540-
LibraryEntity library, ClassEntity cls, IndexedMember member) {
1536+
MemberEntity convertMember(LibraryEntity library, ClassEntity cls,
1537+
IndexedMember member, MemberUsage memberUsage) {
15411538
Name memberName = new Name(member.memberName.text, library,
15421539
isSetter: member.memberName.isSetter);
15431540
if (member.isField) {
@@ -1551,14 +1548,14 @@ class JsKernelToElementMap
15511548
if (constructor.isFactoryConstructor) {
15521549
// TODO(redemption): This should be a JFunction.
15531550
return createFactoryConstructor(
1554-
cls, memberName, constructor.parameterStructure,
1551+
cls, memberName, memberUsage.invokedParameters,
15551552
isExternal: constructor.isExternal,
15561553
isConst: constructor.isConst,
15571554
isFromEnvironmentConstructor:
15581555
constructor.isFromEnvironmentConstructor);
15591556
} else {
15601557
return createGenerativeConstructor(
1561-
cls, memberName, constructor.parameterStructure,
1558+
cls, memberName, memberUsage.invokedParameters,
15621559
isExternal: constructor.isExternal, isConst: constructor.isConst);
15631560
}
15641561
} else if (member.isGetter) {
@@ -1575,8 +1572,8 @@ class JsKernelToElementMap
15751572
isAbstract: setter.isAbstract);
15761573
} else {
15771574
IndexedFunction function = member;
1578-
return createMethod(library, cls, memberName, function.parameterStructure,
1579-
function.asyncMarker,
1575+
return createMethod(library, cls, memberName,
1576+
memberUsage.invokedParameters, function.asyncMarker,
15801577
isStatic: function.isStatic,
15811578
isExternal: function.isExternal,
15821579
isAbstract: function.isAbstract);
@@ -1696,7 +1693,14 @@ class JsKernelToElementMap
16961693
ir.Constructor node, covariant IndexedConstructor constructor) {
16971694
JConstructorDataImpl data = members.getData(constructor);
16981695
if (data.constructorBody == null) {
1699-
JConstructorBody constructorBody = createConstructorBody(constructor);
1696+
/// The constructor calls the constructor body with all parameters.
1697+
// TODO(johnniwinther): Remove parameters that are not used in the
1698+
// constructor body.
1699+
ParameterStructure parameterStructure =
1700+
_getParameterStructureFromFunctionNode(node.function);
1701+
1702+
JConstructorBody constructorBody =
1703+
createConstructorBody(constructor, parameterStructure);
17001704
members.register<IndexedFunction, FunctionData>(
17011705
constructorBody,
17021706
new ConstructorBodyDataImpl(
@@ -1748,7 +1752,8 @@ class JsKernelToElementMap
17481752
void f(DartType type, String name, ConstantValue defaultValue),
17491753
{bool isNative: false}) {
17501754
FunctionData data = members.getData(function);
1751-
data.forEachParameter(this, f, isNative: isNative);
1755+
data.forEachParameter(this, function.parameterStructure, f,
1756+
isNative: isNative);
17521757
}
17531758

17541759
void forEachConstructorBody(
@@ -1820,6 +1825,17 @@ class JsKernelToElementMap
18201825
Local local, Map<Local, JRecordField> recordFieldsVisibleInScope) =>
18211826
recordFieldsVisibleInScope.containsKey(local);
18221827

1828+
ParameterStructure _getParameterStructureFromFunctionNode(
1829+
ir.FunctionNode node) {
1830+
int requiredParameters = node.requiredParameterCount;
1831+
int positionalParameters = node.positionalParameters.length;
1832+
int typeParameters = node.typeParameters.length;
1833+
List<String> namedParameters =
1834+
node.namedParameters.map((p) => p.name).toList()..sort();
1835+
return new ParameterStructure(requiredParameters, positionalParameters,
1836+
namedParameters, typeParameters);
1837+
}
1838+
18231839
KernelClosureClassInfo constructClosureClass(
18241840
MemberEntity member,
18251841
ir.FunctionNode node,
@@ -1863,8 +1879,8 @@ class JsKernelToElementMap
18631879
closureEntity = new AnonymousClosureLocal(classEntity);
18641880
}
18651881

1866-
IndexedFunction callMethod = new JClosureCallMethod(
1867-
classEntity, getParameterStructure(node), getAsyncMarker(node));
1882+
IndexedFunction callMethod = new JClosureCallMethod(classEntity,
1883+
_getParameterStructureFromFunctionNode(node), getAsyncMarker(node));
18681884
_nestedClosureMap
18691885
.putIfAbsent(member, () => <IndexedFunction>[])
18701886
.add(callMethod);

pkg/compiler/lib/src/js_model/elements.dart

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -536,28 +536,26 @@ class JConstructorBody extends JFunction implements ConstructorBodyEntity {
536536

537537
final JConstructor constructor;
538538

539-
JConstructorBody(this.constructor)
540-
: super(
541-
constructor.library,
542-
constructor.enclosingClass,
543-
constructor.memberName,
544-
constructor.parameterStructure,
545-
AsyncMarker.SYNC,
546-
isStatic: false,
547-
isExternal: false);
539+
JConstructorBody(this.constructor, ParameterStructure parameterStructure)
540+
: super(constructor.library, constructor.enclosingClass,
541+
constructor.memberName, parameterStructure, AsyncMarker.SYNC,
542+
isStatic: false, isExternal: false);
548543

549544
factory JConstructorBody.readFromDataSource(DataSource source) {
550545
source.begin(tag);
551546
JConstructor constructor = source.readMember();
547+
ParameterStructure parameterStructure =
548+
new ParameterStructure.readFromDataSource(source);
552549
source.end(tag);
553-
return new JConstructorBody(constructor);
550+
return new JConstructorBody(constructor, parameterStructure);
554551
}
555552

556553
@override
557554
void writeToDataSink(DataSink sink) {
558555
sink.writeEnum(JMemberKind.constructorBody);
559556
sink.begin(tag);
560557
sink.writeMember(constructor);
558+
parameterStructure.writeToDataSink(sink);
561559
sink.end(tag);
562560
}
563561

0 commit comments

Comments
 (0)