Skip to content

Commit

Permalink
Version 3.7.0-161.0.dev
Browse files Browse the repository at this point in the history
Merge cc46252 into dev
  • Loading branch information
Dart CI committed Nov 19, 2024
2 parents 05d5836 + cc46252 commit b01654f
Show file tree
Hide file tree
Showing 13 changed files with 661 additions and 176 deletions.
497 changes: 396 additions & 101 deletions pkg/_fe_analyzer_shared/test/mini_types.dart

Large diffs are not rendered by default.

143 changes: 133 additions & 10 deletions pkg/_fe_analyzer_shared/test/mini_types_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ main() {
'T Function(U, {V y})');
});

test('type formals', () {
expect(
FunctionType(VoidType.instance, [], typeFormals: [t, u]).toString(),
'void Function<T, U>()');
});

test('needs parentheses', () {
expect(
TypeParameterType(t, promotion: FunctionType(VoidType.instance, []))
Expand Down Expand Up @@ -219,7 +225,7 @@ main() {
});
});

group('parse', () {
group('parse:', () {
var throwsParseError = throwsA(TypeMatcher<ParseError>());

group('primary type:', () {
Expand Down Expand Up @@ -409,6 +415,43 @@ main() {
expect(type.namedParameters[1].name, 'y');
});

group('type formals:', () {
test('single', () {
var type = Type('int Function<T>()') as FunctionType;
expect(type.typeFormals, hasLength(1));
expect(type.typeFormals[0].name, 'T');
});

test('multiple', () {
var type = Type('int Function<T, U>()') as FunctionType;
expect(type.typeFormals, hasLength(2));
expect(type.typeFormals[0].name, 'T');
expect(type.typeFormals[1].name, 'U');
});

test('return type and parameters can refer to type formal', () {
var type = Type('T Function<T>(T, {T t})') as FunctionType;
var t = type.typeFormals.single;
expect((type.returnType as TypeParameterType).typeParameter, same(t));
expect(
(type.positionalParameters.single as TypeParameterType)
.typeParameter,
same(t));
expect(
(type.namedParameters.single.type as TypeParameterType)
.typeParameter,
same(t));
});

test('invalid token in type formals', () {
expect(() => Type('int Function<{>()'), throwsParseError);
});

test('invalid token at end of type formals', () {
expect(() => Type('int Function<T}()'), throwsParseError);
});
});

test('invalid parameter separator', () {
expect(() => Type('int Function(String Function()< double)'),
throwsParseError);
Expand Down Expand Up @@ -551,6 +594,25 @@ main() {
Type('void Function({T t})'), Type('void Function({required T t})'));
checkNotEqual(Type('void Function({T t})'), Type('void Function({U t})'));
checkNotEqual(Type('void Function({T t})'), Type('void Function({T u})'));
checkNotEqual(Type('void Function()'), Type('void Function<T>()'));
checkNotEqual(Type('void Function<T, U>(T, U)?'),
Type('void Function<U, T>(U, T)'));
checkEqual(
Type('void Function<T, U>(T, U)'), Type('void Function<U, T>(U, T)'));
checkNotEqual(
Type('void Function<T, U>(T, U)'), Type('void Function<T, U>(U, T)'));
checkEqual(Type('void Function<T, U>({T p1, U p2})'),
Type('void Function<U, T>({U p1, T p2})'));
checkNotEqual(Type('void Function<T, U>({T p1, U p2})'),
Type('void Function<T, U>({U p1, T p2})'));

// For these final test cases, we give one of the type parameters a name
// that would be chosen by `FreshTypeParameterGenerator`, to verify that
// the logic for avoiding name collisions does the right thing.
var t = FreshTypeParameterGenerator().generate().name;
checkEqual(Type('$t Function<$t>()'), Type('U Function<U>()'));
checkNotEqual(Type('void Function<$t>(X Function<X>($t))'),
Type('void Function<$t>($t Function<X>($t))'));
});

test('PrimaryType', () {
Expand Down Expand Up @@ -594,6 +656,12 @@ main() {
checkNotEqual(Type('T&int'), Type('T'));
checkEqual(Type('T&int'), Type('T&int'));
checkNotEqual(Type('T&int'), Type('T&String'));
// Type formals from different function types are not equal
checkNotEqual(
TypeParameterType(
(Type('void Function<T>()') as FunctionType).typeFormals.single),
TypeParameterType(
(Type('void Function<T>()') as FunctionType).typeFormals.single));
});

test('UnknownType', () {
Expand All @@ -602,6 +670,33 @@ main() {
});
});

group('FreshTypeParameterGenerator:', () {
test('generates type parameters with a bound of Object?', () {
var ftpg = FreshTypeParameterGenerator();
expect(ftpg.generate().bound.toString(), 'Object?');
expect(ftpg.generate().bound.toString(), 'Object?');
expect(ftpg.generate().bound.toString(), 'Object?');
});

test('generates a fresh name each time generate is called', () {
var ftpg = FreshTypeParameterGenerator();
expect(ftpg.generate().name, 'T0');
expect(ftpg.generate().name, 'T1');
expect(ftpg.generate().name, 'T2');
});

test('skips names appearing in types passed to excludeNamesUsedIn', () {
var ftpg = FreshTypeParameterGenerator();
TypeRegistry.addInterfaceTypeName('T0');
TypeRegistry.addInterfaceTypeName('T2');
TypeRegistry.addInterfaceTypeName('T3');
ftpg.excludeNamesUsedIn(Type('T0<T2, T3>'));
expect(ftpg.generate().name, 'T1');
expect(ftpg.generate().name, 'T4');
expect(ftpg.generate().name, 'T5');
});
});

group('recursivelyDemote:', () {
group('FunctionType:', () {
group('return type:', () {
Expand All @@ -625,6 +720,14 @@ main() {
.type,
'Never Function()');
});

test('generic', () {
expect(
Type('T&int Function<U>()')
.recursivelyDemote(covariant: true)!
.type,
'T Function<U>()');
});
});

group('positional parameters:', () {
Expand Down Expand Up @@ -841,6 +944,14 @@ main() {
.type,
'Never Function()');
});

test('generic', () {
expect(
Type('_ Function<T>()')
.closureWithRespectToUnknown(covariant: true)!
.type,
'Object? Function<T>()');
});
});

group('positional parameters:', () {
Expand Down Expand Up @@ -1029,8 +1140,8 @@ main() {
}

test('FunctionType', () {
expect(queryUsedIdentifiers(Type('int Function(String, {bool b})')),
unorderedEquals({'int', 'String', 'bool', 'b'}));
expect(queryUsedIdentifiers(Type('int Function<X>(String, {bool b})')),
unorderedEquals({'int', 'X', 'String', 'bool', 'b'}));
});

test('PrimaryType', () {
Expand Down Expand Up @@ -1064,14 +1175,26 @@ main() {

group('substitute:', () {
test('FunctionType', () {
expect(Type('int Function(int, {int i})').substitute({t: Type('String')}),
expect(
Type('int Function<U>(int, {int i})').substitute({t: Type('String')}),
isNull);
expect(Type('T Function(int, {int i})').substitute({t: Type('String')}),
Type('String Function(int, {int i})'));
expect(Type('int Function(T, {int i})?').substitute({t: Type('String')}),
Type('int Function(String, {int i})?'));
expect(Type('int Function(int, {T i})').substitute({t: Type('String')}),
Type('int Function(int, {String i})'));
expect(
Type('T Function<U>(int, {int i})').substitute({t: Type('String')}),
Type('String Function<U>(int, {int i})'));
expect(
Type('int Function<U>(T, {int i})?').substitute({t: Type('String')}),
Type('int Function<U>(String, {int i})?'));
expect(
Type('int Function<U>(int, {T i})').substitute({t: Type('String')}),
Type('int Function<U>(int, {String i})'));
expect(
(Type('int Function<U>(int, {int i})') as FunctionType)
.substitute({t: Type('String')}, dropTypeFormals: true),
Type('int Function(int, {int i})'));
expect(
(Type('int Function<U>(int, {int i})?') as FunctionType)
.substitute({t: Type('String')}, dropTypeFormals: true),
Type('int Function(int, {int i})?'));
expect(Type('int Function(T, T)').substitute({t: Type('String')}),
Type('int Function(String, String)'));
expect(Type('int Function({T t1, T t2})').substitute({t: Type('String')}),
Expand Down
65 changes: 31 additions & 34 deletions pkg/analysis_server/lib/src/server/driver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,10 @@ class Driver implements ServerStarter {

HttpAnalysisServer? httpServer;

Driver();

/// Use the given command-line [arguments] to start this server.
///
/// If [sendPort] is not null, assumes this is launched in an isolate and will
/// connect to the original isolate via an [IsolateChannel].
/// connect to the original isolate via an isolate channel.
@override
void start(
List<String> arguments, {
Expand All @@ -163,40 +161,39 @@ class Driver implements ServerStarter {

var analysisServerOptions = AnalysisServerOptions();
analysisServerOptions.newAnalysisDriverLog =
(results[ANALYSIS_DRIVER_LOG] ?? results[ANALYSIS_DRIVER_LOG_ALIAS])
as String?;
results.option(ANALYSIS_DRIVER_LOG) ??
results.option(ANALYSIS_DRIVER_LOG_ALIAS);
if (results.wasParsed(USE_LSP)) {
analysisServerOptions.useLanguageServerProtocol =
results[USE_LSP] as bool;
analysisServerOptions.useLanguageServerProtocol = results.flag(USE_LSP);
} else {
analysisServerOptions.useLanguageServerProtocol =
results[SERVER_PROTOCOL] == PROTOCOL_LSP;
results.option(SERVER_PROTOCOL) == PROTOCOL_LSP;
}
// For clients that don't supply their own identifier, use a default based
// on whether the server will run in LSP mode or not.
var clientId =
(results[CLIENT_ID] as String?) ??
results.option(CLIENT_ID) ??
(analysisServerOptions.useLanguageServerProtocol
? 'unknown.client.lsp'
: 'unknown.client.classic');
analysisServerOptions.clientId = clientId;
analysisServerOptions.clientVersion = results[CLIENT_VERSION] as String?;
analysisServerOptions.cacheFolder = results[CACHE_FOLDER] as String?;
analysisServerOptions.packagesFile = results[PACKAGES_FILE] as String?;
analysisServerOptions.reportProtocolVersion =
results[REPORT_PROTOCOL_VERSION] as String?;
analysisServerOptions.clientVersion = results.option(CLIENT_VERSION);
analysisServerOptions.cacheFolder = results.option(CACHE_FOLDER);
analysisServerOptions.packagesFile = results.option(PACKAGES_FILE);
analysisServerOptions.reportProtocolVersion = results.option(
REPORT_PROTOCOL_VERSION,
);

analysisServerOptions.enabledExperiments =
results.wasParsed(ENABLE_EXPERIMENT)
? results[ENABLE_EXPERIMENT] as List<String>
: <String>[];
analysisServerOptions.enabledExperiments = results.multiOption(
ENABLE_EXPERIMENT,
);

// Read in any per-SDK overrides specified in <sdk>/config/settings.json.
var sdkConfig = SdkConfiguration.readFromSdk();
analysisServerOptions.configurationOverrides = sdkConfig;

// Analytics (legacy, and unified)
var disableAnalyticsForSession = results[SUPPRESS_ANALYTICS_FLAG] as bool;
var disableAnalyticsForSession = results.flag(SUPPRESS_ANALYTICS_FLAG);

if (results.wasParsed(TRAIN_USING)) {
disableAnalyticsForSession = true;
Expand Down Expand Up @@ -247,9 +244,8 @@ class Driver implements ServerStarter {
);

{
var disableCompletion =
results[DISABLE_SERVER_FEATURE_COMPLETION] as bool;
var disableSearch = results[DISABLE_SERVER_FEATURE_SEARCH] as bool;
var disableCompletion = results.flag(DISABLE_SERVER_FEATURE_COMPLETION);
var disableSearch = results.flag(DISABLE_SERVER_FEATURE_SEARCH);
if (disableCompletion || disableSearch) {
analysisServerOptions.featureSet = FeatureSet(
completion: !disableCompletion,
Expand All @@ -258,7 +254,7 @@ class Driver implements ServerStarter {
}
}

if (results[HELP_OPTION] as bool) {
if (results.flag(HELP_OPTION)) {
_printUsage(parser, fromHelp: true);
return;
}
Expand All @@ -274,8 +270,8 @@ class Driver implements ServerStarter {
// Initialize the instrumentation service.
//
var logFilePath =
(results[PROTOCOL_TRAFFIC_LOG] ?? results[PROTOCOL_TRAFFIC_LOG_ALIAS])
as String?;
results.option(PROTOCOL_TRAFFIC_LOG) ??
results.option(PROTOCOL_TRAFFIC_LOG_ALIAS);
var allInstrumentationServices =
this.instrumentationService == null
? <InstrumentationService>[]
Expand All @@ -301,7 +297,7 @@ class Driver implements ServerStarter {
this.instrumentationService = instrumentationService;

instrumentationService.logVersion(
results[TRAIN_USING] != null
results.option(TRAIN_USING) != null
? 'training-0'
: _readUuid(instrumentationService),
analysisServerOptions.clientId ?? '',
Expand All @@ -313,7 +309,8 @@ class Driver implements ServerStarter {

int? diagnosticServerPort;
var portValue =
(results[DIAGNOSTIC_PORT] ?? results[DIAGNOSTIC_PORT_ALIAS]) as String?;
results.option(DIAGNOSTIC_PORT) ??
results.option(DIAGNOSTIC_PORT_ALIAS);
if (portValue != null) {
try {
diagnosticServerPort = int.parse(portValue);
Expand Down Expand Up @@ -380,10 +377,10 @@ class Driver implements ServerStarter {
SendPort? sendPort,
) {
var capture =
results[DISABLE_SERVER_EXCEPTION_HANDLING] as bool
? (_, Function f, {Function(String)? print}) => f()
results.flag(DISABLE_SERVER_EXCEPTION_HANDLING)
? (_, Function f, {void Function(String)? print}) => f()
: _captureExceptions;
var trainDirectory = results[TRAIN_USING] as String?;
var trainDirectory = results.option(TRAIN_USING);
if (trainDirectory != null) {
if (!FileSystemEntity.isDirectorySync(trainDirectory)) {
print("Training directory '$trainDirectory' not found.\n");
Expand Down Expand Up @@ -472,7 +469,7 @@ class Driver implements ServerStarter {
serveResult = isolateAnalysisServer.serveIsolate(sendPort);
}
errorNotifier.server = socketServer.analysisServer;
if (results[DISABLE_SILENT_ANALYSIS_EXCEPTIONS] as bool) {
if (results.flag(DISABLE_SILENT_ANALYSIS_EXCEPTIONS)) {
errorNotifier.sendSilentExceptionsToClient = true;
}
serveResult.then((_) async {
Expand All @@ -486,7 +483,7 @@ class Driver implements ServerStarter {
});
},
print:
results[INTERNAL_PRINT_TO_CONSOLE] as bool
results.flag(INTERNAL_PRINT_TO_CONSOLE)
? null
: httpServer!.recordPrint,
);
Expand All @@ -503,8 +500,8 @@ class Driver implements ServerStarter {
ErrorNotifier errorNotifier,
) {
var capture =
args[DISABLE_SERVER_EXCEPTION_HANDLING] as bool
? (_, Function f, {Function(String)? print}) => f()
args.flag(DISABLE_SERVER_EXCEPTION_HANDLING)
? (_, Function f, {void Function(String)? print}) => f()
: _captureExceptions;

linter.registerLintRules();
Expand Down
Loading

0 comments on commit b01654f

Please sign in to comment.