Skip to content

Event.message: accept String or Function to avoid String interpolation. #56454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,22 @@ enum ConstraintGenerationSource {
/// Representation of a single event in the inference log, with pointers to any
/// events that are nested beneath it.
class Event {
final Object _message;

/// Message display string.
final String message;
String get message {
var m = _message;
if (m is Function()) {
return m();
} else {
return m.toString();
}
}

/// List of nested events.
List<Event>? subEvents;

Event({required this.message});
Event({required Object message}) : _message = message;
}

/// Specialization of [State] used when type inferring an expression.
Expand Down Expand Up @@ -392,7 +401,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
pushState(new State(
kind: StateKind.annotation,
writer: this,
message: 'INFER ANNOTATION ${describe(node)}',
message: () => 'INFER ANNOTATION ${describe(node)}',
nodeSet: [node]));
}

Expand All @@ -406,7 +415,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
pushState(new State(
kind: StateKind.constraintGeneration,
writer: this,
message: 'GENERATE CONSTRAINTS FOR $source: $p <# $q',
message: () => 'GENERATE CONSTRAINTS FOR $source: $p <# $q',
nodeSet: state.nodeSet));
}

Expand All @@ -415,15 +424,16 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
pushState(new State(
kind: StateKind.collectionElement,
writer: this,
message: 'INFER ELEMENT ${describe(node)}',
message: () => 'INFER ELEMENT ${describe(node)}',
nodeSet: [node]));
}

@override
void enterExpression(Object node, Type contextType) {
pushState(new ExpressionState(
writer: this,
message: 'INFER EXPRESSION ${describe(node)} IN CONTEXT $contextType',
message: () =>
'INFER EXPRESSION ${describe(node)} IN CONTEXT $contextType',
nodeSet: [node]));
}

Expand All @@ -432,7 +442,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
pushState(new State(
kind: StateKind.extensionOverride,
writer: this,
message: 'INFER EXTENSION OVERRIDE ${describe(node)} IN CONTEXT '
message: () => 'INFER EXTENSION OVERRIDE ${describe(node)} IN CONTEXT '
'$contextType',
nodeSet: [node]));
}
Expand All @@ -441,7 +451,8 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
void enterFunctionExpressionInvocationTarget(Object node) {
pushState(new ExpressionState(
writer: this,
message: 'REINTERPRET METHOD NAME ${describe(node)} AS AN EXPRESSION',
message: () =>
'REINTERPRET METHOD NAME ${describe(node)} AS AN EXPRESSION',
nodeSet: [node]));
}

Expand All @@ -456,7 +467,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
].join(', ');
pushState(new GenericInferenceState(
writer: this,
message: 'FIND $typeFormalNames IN $template',
message: () => 'FIND $typeFormalNames IN $template',
parent: state,
typeFormals: typeFormals));
}
Expand All @@ -466,7 +477,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
pushState(new State(
kind: StateKind.lValue,
writer: this,
message: 'INFER LVALUE ${describe(node)}',
message: () => 'INFER LVALUE ${describe(node)}',
nodeSet: [node]));
}

Expand All @@ -475,7 +486,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
pushState(new State(
kind: StateKind.pattern,
writer: this,
message: 'INFER PATTERN ${describe(node)}',
message: () => 'INFER PATTERN ${describe(node)}',
nodeSet: [node]));
}

Expand All @@ -484,7 +495,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
pushState(new State(
kind: StateKind.statement,
writer: this,
message: 'INFER STATEMENT ${describe(node)}',
message: () => 'INFER STATEMENT ${describe(node)}',
nodeSet: [node]));
}

Expand Down Expand Up @@ -573,7 +584,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
'${typeFormals[i]}=${finalTypes[i]}'
];
addEvent(new Event(
message: 'FINAL GENERIC TYPES ${typeAssignments.join(', ')}'));
message: () => 'FINAL GENERIC TYPES ${typeAssignments.join(', ')}'));
}
popState();
}
Expand Down Expand Up @@ -620,7 +631,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
/// an event showing the failure [message], and then an exception is thrown.
Never fail(String message) {
dump();
addEvent(new Event(message: 'FAILURE: $message'));
addEvent(new Event(message: () => 'FAILURE: $message'));
throw new StateError(message);
}

Expand Down Expand Up @@ -655,7 +666,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
expectedNode: oldExpression,
expectedKind: StateKind.expression);
addEvent(new Event(
message: 'REWRITE ${describe(oldExpression)} TO '
message: () => 'REWRITE ${describe(oldExpression)} TO '
'${describe(newExpression)}'));
(state as ExpressionState).nodeSet.add(newExpression);
if (oldExpression != null) {
Expand All @@ -673,8 +684,8 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
arguments: [expression],
expectedNode: expression,
expectedKind: StateKind.expression);
addEvent(
new Event(message: 'EXPRESSION ${describe(expression)} HAS NO TYPE'));
addEvent(new Event(
message: () => 'EXPRESSION ${describe(expression)} HAS NO TYPE'));
ExpressionState state = this.state as ExpressionState;
if (state.typeRecorded) {
fail('A type (or lack thereof) was already recorded for this expression');
Expand All @@ -691,9 +702,11 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
method: 'recordGeneratedConstraint',
arguments: [parameter, constraint],
expectedKind: StateKind.constraintGeneration);
String constraintText =
constraint.toString().replaceAll('<type>', parameter.toString());
addEvent(new Event(message: 'ADDED CONSTRAINT $constraintText'));
addEvent(new Event(message: () {
String constraintText =
constraint.toString().replaceAll('<type>', parameter.toString());
return 'ADDED CONSTRAINT $constraintText';
}));
}

@override
Expand All @@ -714,7 +727,7 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
expectedKind: StateKind.expression);
String query =
target != null ? '${describe(target)}.$methodName' : methodName;
addEvent(new Event(message: 'LOOKUP $query FINDS $type'));
addEvent(new Event(message: () => 'LOOKUP $query FINDS $type'));
}

@override
Expand All @@ -723,12 +736,13 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
method: 'recordPreliminaryTypes',
arguments: [types],
expectedKind: StateKind.genericInference);
List<Object> typeFormals = (state as GenericInferenceState).typeFormals;
List<String> typeAssignments = [
for (int i = 0; i < types.length; i++) '${typeFormals[i]}=${types[i]}'
];
addEvent(new Event(
message: 'PRELIMINARY GENERIC TYPES ${typeAssignments.join(', ')}'));
addEvent(new Event(message: () {
List<Object> typeFormals = (state as GenericInferenceState).typeFormals;
List<String> typeAssignments = [
for (int i = 0; i < types.length; i++) '${typeFormals[i]}=${types[i]}'
];
return 'PRELIMINARY GENERIC TYPES ${typeAssignments.join(', ')}';
}));
}

@override
Expand All @@ -738,8 +752,8 @@ abstract class SharedInferenceLogWriterImpl<Type extends SharedType<Type>,
arguments: [expression, type],
expectedNode: expression,
expectedKind: StateKind.expression);
addEvent(
new Event(message: 'STATIC TYPE OF ${describe(expression)} IS $type'));
addEvent(new Event(
message: () => 'STATIC TYPE OF ${describe(expression)} IS $type'));
ExpressionState state = this.state as ExpressionState;
if (state.typeRecorded) {
fail('A type (or lack thereof) was already recorded for this expression');
Expand Down