[analysis_server] have a single function for union
Bug: #49229 Change-Id: I6141c48e48fbe88812c10d7fcc3541af28ec36c6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247966 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Danny Tuppeny <danny@tuppeny.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
@@ -1945,11 +1945,7 @@ class RequestMessage implements IncomingMessage, ToJsonable {
|
||||
final clientRequestTimeJson = json['clientRequestTime'];
|
||||
final clientRequestTime = clientRequestTimeJson as int?;
|
||||
final idJson = json['id'];
|
||||
final id = idJson is int
|
||||
? Either2<int, String>.t1(idJson)
|
||||
: (idJson is String
|
||||
? Either2<int, String>.t2(idJson)
|
||||
: (throw '''$idJson was not one of (int, String)'''));
|
||||
final id = _eitherIntString(idJson);
|
||||
final jsonrpcJson = json['jsonrpc'];
|
||||
final jsonrpc = jsonrpcJson as String;
|
||||
final methodJson = json['method'];
|
||||
@@ -2226,13 +2222,7 @@ class ResponseMessage implements Message, ToJsonable {
|
||||
? ResponseError.fromJson(errorJson as Map<String, Object?>)
|
||||
: null;
|
||||
final idJson = json['id'];
|
||||
final id = idJson == null
|
||||
? null
|
||||
: (idJson is int
|
||||
? Either2<int, String>.t1(idJson)
|
||||
: (idJson is String
|
||||
? Either2<int, String>.t2(idJson)
|
||||
: (throw '''$idJson was not one of (int, String)''')));
|
||||
final id = idJson == null ? null : _eitherIntString(idJson);
|
||||
final jsonrpcJson = json['jsonrpc'];
|
||||
final jsonrpc = jsonrpcJson as String;
|
||||
final resultJson = json['result'];
|
||||
@@ -2574,3 +2564,11 @@ class ValidateRefactorResult implements ToJsonable {
|
||||
@override
|
||||
String toString() => jsonEncoder.convert(toJson());
|
||||
}
|
||||
|
||||
Either2<int, String> _eitherIntString(Object? value) {
|
||||
return value is int
|
||||
? Either2.t1(value)
|
||||
: value is String
|
||||
? Either2.t2(value)
|
||||
: throw '$value was not one of (int, String)';
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,9 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:analyzer_utilities/tools.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:dart_style/dart_style.dart';
|
||||
|
||||
@@ -13,6 +16,7 @@ Map<String, Interface> _interfaces = {};
|
||||
Map<String, LspEnum> _namespaces = {};
|
||||
Map<String, List<String>> _subtypes = {};
|
||||
Map<String, TypeAlias> _typeAliases = {};
|
||||
var _unionFunctions = SplayTreeMap<String, String>();
|
||||
|
||||
/// Whether our enum class allows any value (eg. should always return true
|
||||
/// from canParse() for the correct type). This is to allow us to have some
|
||||
@@ -35,12 +39,17 @@ bool enumClassAllowsAnyValue(String name) {
|
||||
}
|
||||
|
||||
String generateDartForTypes(List<LspEntity> types) {
|
||||
_unionFunctions.clear();
|
||||
final buffer = IndentableStringBuffer();
|
||||
_getSortedUnique(types).forEach((t) => _writeType(buffer, t));
|
||||
for (var function in _unionFunctions.values) {
|
||||
buffer.writeln(function);
|
||||
}
|
||||
|
||||
final stopwatch = Stopwatch()..start();
|
||||
final formattedCode = _formatCode(buffer.toString());
|
||||
stopwatch.stop();
|
||||
if (stopwatch.elapsed.inSeconds > 10) {
|
||||
if (stopwatch.elapsed.inSeconds > 3) {
|
||||
print('WARN: Formatting took ${stopwatch.elapsed} (${types.length} types)');
|
||||
}
|
||||
return '${formattedCode.trim()}\n'; // Ensure a single trailing newline.
|
||||
@@ -627,7 +636,26 @@ void _writeFromJsonCode(
|
||||
_writeFromJsonCodeForLiteralUnion(buffer, type, valueCode,
|
||||
allowsNull: allowsNull);
|
||||
} else if (type is UnionType) {
|
||||
_writeFromJsonCodeForUnion(buffer, type, valueCode, allowsNull: allowsNull);
|
||||
var functionName = type.types.map((t) {
|
||||
if (t is TypeReference) {
|
||||
t = resolveTypeAlias(t);
|
||||
}
|
||||
var dartType =
|
||||
t is UnionType ? t.types.map((e) => e.dartType).join() : t.dartType;
|
||||
return capitalize(dartType);
|
||||
}).join();
|
||||
|
||||
functionName = '_either$functionName';
|
||||
|
||||
if (allowsNull) {
|
||||
buffer.write('$valueCode == null ? null : ');
|
||||
}
|
||||
buffer.write('$functionName($valueCode)');
|
||||
if (!_unionFunctions.containsKey(functionName)) {
|
||||
var temp = IndentableStringBuffer();
|
||||
_writeFromJsonCodeForUnion(temp, type, functionName);
|
||||
_unionFunctions[functionName] = temp.toString();
|
||||
}
|
||||
} else {
|
||||
buffer.write('$valueCode$cast');
|
||||
}
|
||||
@@ -644,22 +672,19 @@ void _writeFromJsonCodeForLiteralUnion(
|
||||
final cast = ' as $valueType${allowsNull ? '?' : ''}';
|
||||
buffer.write(
|
||||
"const {${allowedValues.join(', ')}}.contains($valueCode) ? $valueCode$cast : "
|
||||
"throw '''\$$valueCode was not one of (${allowedValues.join(', ')})'''");
|
||||
"throw \"\$$valueCode was not one of (${allowedValues.join(', ')})\"");
|
||||
}
|
||||
|
||||
void _writeFromJsonCodeForUnion(
|
||||
IndentableStringBuffer buffer, UnionType union, String valueCode,
|
||||
{required bool allowsNull}) {
|
||||
// Write a check against each type, eg.:
|
||||
// x is y ? new Either.tx(x) : (...)
|
||||
var hasIncompleteCondition = false;
|
||||
var unclosedParens = 0;
|
||||
IndentableStringBuffer buffer, UnionType union, String functionName) {
|
||||
buffer
|
||||
..writeln('${union.dartTypeWithTypeArgs} $functionName(Object? value) {')
|
||||
..indent()
|
||||
..writeIndented('return ');
|
||||
|
||||
if (allowsNull) {
|
||||
buffer.write('$valueCode == null ? null : (');
|
||||
hasIncompleteCondition = true;
|
||||
unclosedParens++;
|
||||
}
|
||||
// Write a check against each type, eg.:
|
||||
// x is y ? Either.tx(x) : (...)
|
||||
var hasIncompleteCondition = false;
|
||||
|
||||
for (var i = 0; i < union.types.length; i++) {
|
||||
final type = union.types[i];
|
||||
@@ -668,15 +693,15 @@ void _writeFromJsonCodeForUnion(
|
||||
// "any" matches all type checks, so only emit it if required.
|
||||
if (!isAny) {
|
||||
_writeTypeCheckCondition(
|
||||
buffer, null, valueCode, type, 'nullLspJsonReporter');
|
||||
buffer, null, 'value', type, 'nullLspJsonReporter');
|
||||
buffer.write(' ? ');
|
||||
}
|
||||
|
||||
// The code to construct a value with this "side" of the union.
|
||||
buffer.write('${union.dartTypeWithTypeArgs}.t${i + 1}(');
|
||||
buffer.write('${union.dartType}.t${i + 1}(');
|
||||
// Call recursively as unions may be nested.
|
||||
_writeFromJsonCode(
|
||||
buffer, type, valueCode,
|
||||
buffer, type, 'value',
|
||||
// null + type checks are already handled above this loop
|
||||
allowsNull: false,
|
||||
requiresCast: false,
|
||||
@@ -685,9 +710,8 @@ void _writeFromJsonCodeForUnion(
|
||||
|
||||
// If we output the type condition at the top, prepare for the next condition.
|
||||
if (!isAny) {
|
||||
buffer.write(' : (');
|
||||
buffer.write(' : ');
|
||||
hasIncompleteCondition = true;
|
||||
unclosedParens++;
|
||||
} else {
|
||||
hasIncompleteCondition = false;
|
||||
}
|
||||
@@ -695,11 +719,13 @@ void _writeFromJsonCodeForUnion(
|
||||
// Fill the final parens with a throw because if we fell through all of the
|
||||
// cases then the value we had didn't match any of the types in the union.
|
||||
if (hasIncompleteCondition) {
|
||||
var interpolation = '\$$valueCode';
|
||||
buffer.write(
|
||||
"throw '''$interpolation was not one of (${union.types.map((t) => t.dartTypeWithTypeArgs).join(', ')})'''");
|
||||
"throw '\$value was not one of (${union.types.map((t) => t.dartTypeWithTypeArgs).join(', ')})'");
|
||||
}
|
||||
buffer.write(')' * unclosedParens);
|
||||
buffer
|
||||
..writeln(';')
|
||||
..outdent()
|
||||
..writeln('}');
|
||||
}
|
||||
|
||||
void _writeFromJsonConstructor(
|
||||
|
||||
Reference in New Issue
Block a user