mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:00:09 +00:00
Store CallStructure in StaticUse
- in preparation for tracking unused optional arguments of static methods Change-Id: I8a9b1d0d9acd57256d383f880b9c602d91804486 Reviewed-on: https://dart-review.googlesource.com/29801 Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
72443f777d
commit
66398a511a
|
@ -9,6 +9,7 @@ import '../constants/expressions.dart';
|
|||
import '../elements/elements.dart';
|
||||
import '../elements/entities.dart';
|
||||
import '../elements/resolution_types.dart';
|
||||
import '../universe/call_structure.dart';
|
||||
import '../universe/feature.dart';
|
||||
import '../universe/selector.dart';
|
||||
import '../universe/use.dart';
|
||||
|
@ -84,6 +85,10 @@ class ImpactSerializer implements WorldImpactVisitor {
|
|||
if (staticUse.type != null) {
|
||||
object.setType(Key.TYPE, staticUse.type);
|
||||
}
|
||||
if (staticUse.callStructure != null) {
|
||||
serializeCallStructure(
|
||||
staticUse.callStructure, object.createObject(Key.CALL_STRUCTURE));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -148,7 +153,14 @@ class ImpactDeserializer {
|
|||
Element usedElement =
|
||||
deserializeElementReference(element, Key.ELEMENT, Key.NAME, object);
|
||||
ResolutionDartType type = object.getType(Key.TYPE, isOptional: true);
|
||||
staticUses.add(new StaticUse.internal(usedElement, kind, type));
|
||||
ObjectDecoder callStructureObject =
|
||||
object.getObject(Key.CALL_STRUCTURE, isOptional: true);
|
||||
CallStructure callStructure;
|
||||
if (callStructureObject != null) {
|
||||
callStructure = deserializeCallStructure(callStructureObject);
|
||||
}
|
||||
staticUses.add(new StaticUse.internal(usedElement, kind,
|
||||
type: type, callStructure: callStructure));
|
||||
}
|
||||
|
||||
ListDecoder dynamicUseDecoder = objectDecoder.getList(Key.DYNAMIC_USES);
|
||||
|
|
|
@ -37,24 +37,33 @@ Name deserializeName(ObjectDecoder decoder) {
|
|||
return new Name(name, library, isSetter: isSetter);
|
||||
}
|
||||
|
||||
/// Serialize [callStructure] into [encoder].
|
||||
void serializeCallStructure(
|
||||
CallStructure callStructure, ObjectEncoder encoder) {
|
||||
encoder.setInt(Key.ARGUMENTS, callStructure.argumentCount);
|
||||
encoder.setStrings(Key.NAMED_ARGUMENTS, callStructure.namedArguments);
|
||||
}
|
||||
|
||||
/// Serialize [selector] into [encoder].
|
||||
void serializeSelector(Selector selector, ObjectEncoder encoder) {
|
||||
encoder.setEnum(Key.KIND, selector.kind);
|
||||
|
||||
encoder.setInt(Key.ARGUMENTS, selector.callStructure.argumentCount);
|
||||
encoder.setStrings(
|
||||
Key.NAMED_ARGUMENTS, selector.callStructure.namedArguments);
|
||||
serializeCallStructure(selector.callStructure, encoder);
|
||||
serializeName(selector.memberName, encoder);
|
||||
}
|
||||
|
||||
/// Deserialize a [CallStructure] from [decoder].
|
||||
CallStructure deserializeCallStructure(ObjectDecoder decoder) {
|
||||
int argumentCount = decoder.getInt(Key.ARGUMENTS);
|
||||
List<String> namedArguments =
|
||||
decoder.getStrings(Key.NAMED_ARGUMENTS, isOptional: true);
|
||||
return new CallStructure(argumentCount, namedArguments);
|
||||
}
|
||||
|
||||
/// Deserialize a [Selector] from [decoder].
|
||||
Selector deserializeSelector(ObjectDecoder decoder) {
|
||||
SelectorKind kind = decoder.getEnum(Key.KIND, SelectorKind.values);
|
||||
int argumentCount = decoder.getInt(Key.ARGUMENTS);
|
||||
List<String> namedArguments =
|
||||
decoder.getStrings(Key.NAMED_ARGUMENTS, isOptional: true);
|
||||
return new Selector(kind, deserializeName(decoder),
|
||||
new CallStructure(argumentCount, namedArguments));
|
||||
CallStructure callStructure = deserializeCallStructure(decoder);
|
||||
return new Selector(kind, deserializeName(decoder), callStructure);
|
||||
}
|
||||
|
||||
/// Serialize [sendStructure] into [encoder].
|
||||
|
|
|
@ -95,12 +95,12 @@ class StaticUse {
|
|||
final StaticUseKind kind;
|
||||
final int hashCode;
|
||||
final DartType type;
|
||||
final CallStructure callStructure;
|
||||
|
||||
StaticUse.internal(Entity element, StaticUseKind kind, [DartType type = null])
|
||||
StaticUse.internal(Entity element, this.kind, {this.type, this.callStructure})
|
||||
: this.element = element,
|
||||
this.kind = kind,
|
||||
this.type = type,
|
||||
this.hashCode = Hashing.objectsHash(element, kind, type) {
|
||||
this.hashCode =
|
||||
Hashing.objectsHash(element, kind, type, callStructure) {
|
||||
assert(
|
||||
!(element is Element && !element.isDeclaration),
|
||||
failedAt(element,
|
||||
|
@ -111,14 +111,14 @@ class StaticUse {
|
|||
/// [callStructure].
|
||||
factory StaticUse.staticInvoke(
|
||||
FunctionEntity element, CallStructure callStructure) {
|
||||
// TODO(johnniwinther): Use the [callStructure].
|
||||
assert(
|
||||
element.isStatic || element.isTopLevel,
|
||||
failedAt(
|
||||
element,
|
||||
"Static invoke element $element must be a top-level "
|
||||
"or static method."));
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL);
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL,
|
||||
callStructure: callStructure);
|
||||
}
|
||||
|
||||
/// Closurization of a static or top-level function [element].
|
||||
|
@ -179,12 +179,12 @@ class StaticUse {
|
|||
/// Invocation of a super method [element] with the given [callStructure].
|
||||
factory StaticUse.superInvoke(
|
||||
FunctionEntity element, CallStructure callStructure) {
|
||||
// TODO(johnniwinther): Use the [callStructure].
|
||||
assert(
|
||||
element.isInstanceMember,
|
||||
failedAt(element,
|
||||
"Super invoke element $element must be an instance method."));
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL);
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL,
|
||||
callStructure: callStructure);
|
||||
}
|
||||
|
||||
/// Read access of a super field or getter [element].
|
||||
|
@ -235,35 +235,35 @@ class StaticUse {
|
|||
/// constructor call with the given [callStructure].
|
||||
factory StaticUse.superConstructorInvoke(
|
||||
ConstructorEntity element, CallStructure callStructure) {
|
||||
// TODO(johnniwinther): Use the [callStructure].
|
||||
assert(
|
||||
element.isGenerativeConstructor,
|
||||
failedAt(
|
||||
element,
|
||||
"Constructor invoke element $element must be a "
|
||||
"generative constructor."));
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL);
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL,
|
||||
callStructure: callStructure);
|
||||
}
|
||||
|
||||
/// Invocation of a constructor (body) [element] through a this or super
|
||||
/// constructor call with the given [callStructure].
|
||||
factory StaticUse.constructorBodyInvoke(
|
||||
ConstructorBodyEntity element, CallStructure callStructure) {
|
||||
// TODO(johnniwinther): Use the [callStructure].
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL);
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL,
|
||||
callStructure: callStructure);
|
||||
}
|
||||
|
||||
/// Direct invocation of a method [element] with the given [callStructure].
|
||||
factory StaticUse.directInvoke(
|
||||
FunctionEntity element, CallStructure callStructure) {
|
||||
// TODO(johnniwinther): Use the [callStructure].
|
||||
assert(
|
||||
element.isInstanceMember,
|
||||
failedAt(element,
|
||||
"Direct invoke element $element must be an instance member."));
|
||||
assert(element.isFunction,
|
||||
failedAt(element, "Direct invoke element $element must be a method."));
|
||||
return new StaticUse.internal(element, StaticUseKind.DIRECT_INVOKE);
|
||||
return new StaticUse.internal(element, StaticUseKind.DIRECT_INVOKE,
|
||||
callStructure: callStructure);
|
||||
}
|
||||
|
||||
/// Direct read access of a field or getter [element].
|
||||
|
@ -297,8 +297,8 @@ class StaticUse {
|
|||
element.isConstructor,
|
||||
failedAt(element,
|
||||
"Constructor invocation element $element must be a constructor."));
|
||||
// TODO(johnniwinther): Use the [callStructure].
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL);
|
||||
return new StaticUse.internal(element, StaticUseKind.GENERAL,
|
||||
callStructure: callStructure);
|
||||
}
|
||||
|
||||
/// Constructor invocation of [element] with the given [callStructure] on
|
||||
|
@ -313,9 +313,8 @@ class StaticUse {
|
|||
element,
|
||||
"Typed constructor invocation element $element "
|
||||
"must be a constructor."));
|
||||
// TODO(johnniwinther): Use the [callStructure].
|
||||
return new StaticUse.internal(
|
||||
element, StaticUseKind.CONSTRUCTOR_INVOKE, type);
|
||||
return new StaticUse.internal(element, StaticUseKind.CONSTRUCTOR_INVOKE,
|
||||
type: type, callStructure: callStructure);
|
||||
}
|
||||
|
||||
/// Constant constructor invocation of [element] with the given
|
||||
|
@ -330,9 +329,9 @@ class StaticUse {
|
|||
element,
|
||||
"Const constructor invocation element $element "
|
||||
"must be a constructor."));
|
||||
// TODO(johnniwinther): Use the [callStructure].
|
||||
return new StaticUse.internal(
|
||||
element, StaticUseKind.CONST_CONSTRUCTOR_INVOKE, type);
|
||||
element, StaticUseKind.CONST_CONSTRUCTOR_INVOKE,
|
||||
type: type, callStructure: callStructure);
|
||||
}
|
||||
|
||||
/// Constructor redirection to [element] on [type].
|
||||
|
@ -344,7 +343,8 @@ class StaticUse {
|
|||
element.isConstructor,
|
||||
failedAt(element,
|
||||
"Constructor redirection element $element must be a constructor."));
|
||||
return new StaticUse.internal(element, StaticUseKind.REDIRECTION, type);
|
||||
return new StaticUse.internal(element, StaticUseKind.REDIRECTION,
|
||||
type: type);
|
||||
}
|
||||
|
||||
/// Initialization of an instance field [element].
|
||||
|
@ -407,17 +407,20 @@ class StaticUse {
|
|||
/// Inlining of [element].
|
||||
factory StaticUse.inlining(
|
||||
FunctionEntity element, InterfaceType instanceType) {
|
||||
return new StaticUse.internal(
|
||||
element, StaticUseKind.INLINING, instanceType);
|
||||
return new StaticUse.internal(element, StaticUseKind.INLINING,
|
||||
type: instanceType);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
if (identical(this, other)) return true;
|
||||
if (other is! StaticUse) return false;
|
||||
return element == other.element && kind == other.kind && type == other.type;
|
||||
return element == other.element &&
|
||||
kind == other.kind &&
|
||||
type == other.type &&
|
||||
callStructure == other.callStructure;
|
||||
}
|
||||
|
||||
String toString() => 'StaticUse($element,$kind,$type)';
|
||||
String toString() => 'StaticUse($element,$kind,$type,$callStructure)';
|
||||
}
|
||||
|
||||
enum TypeUseKind {
|
||||
|
|
|
@ -43,8 +43,9 @@ class Hashing {
|
|||
}
|
||||
|
||||
/// Mix the bits of `.hashCode` all non-null objects.
|
||||
static int objectsHash(Object obj1, [Object obj2, Object obj3]) {
|
||||
static int objectsHash(Object obj1, [Object obj2, Object obj3, Object obj4]) {
|
||||
int hash = 0;
|
||||
if (obj4 != null) hash = objectHash(obj4, hash);
|
||||
if (obj3 != null) hash = objectHash(obj3, hash);
|
||||
if (obj2 != null) hash = objectHash(obj2, hash);
|
||||
return objectHash(obj1, hash);
|
||||
|
|
Loading…
Reference in a new issue