blob: 6d386fb857005dd197d69743dc417e37f0f9b08b [file]
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// 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 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../utils/test_code_extensions.dart';
import 'server_abstract.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(InlineValueTest);
});
}
@reflectiveTest
class InlineValueTest extends AbstractLspAnalysisServerTest {
late TestCode code;
Future<void> test_parameter_declaration() async {
code = TestCode.parse(r'''
void f(int /*[0*/aaa/*0]*/, int /*[1*/bbb/*1]*/) {
^
aaa + bbb;
}
''');
await verify_variables(code);
}
Future<void> test_parameter_read() async {
code = TestCode.parse(r'''
void f(int aaa, int bbb) {
^/*[0*/aaa/*0]*/ + /*[1*/bbb/*1]*/;
}
''');
await verify_variables(code);
}
Future<void> test_parameter_write() async {
code = TestCode.parse(r'''
void f(int aaa, int bbb, int ccc) {
/*[0*/aaa/*0]*/++;
/*[1*/bbb/*1]*/ = 1;
/*[2*/ccc/*2]*/ += 1;
^
}
''');
await verify_variables(code);
}
Future<void> test_parameters_scope() async {
// We should only get the parameters declared in the current function.
code = TestCode.parse(r'''
void f(int aaa, int bbb, int ccc) {
void b(int /*[0*/aaa/*0]*/, int /*[1*/bbb/*1]*/) {
var _ = (aaa, bbb, ccc) => null;
var _ = () {
var aaa = 1, bbb = 1, ccc = 1;
};
^
}
}
''');
await verify_variables(code);
}
Future<void> test_variable_declaration() async {
code = TestCode.parse(r'''
void f() {
int /*[0*/aaa/*0]*/ = 1;
int /*[1*/bbb/*1]*/ = 1, /*[2*/ccc/*2]*/ = 1;
^
aaa + bbb;
ccc;
}
''');
await verify_variables(code);
}
Future<void> test_variable_read() async {
code = TestCode.parse(r'''
void f() {
int aaa = 1;
int bbb = 1, ccc = 1;
^/*[0*/aaa/*0]*/ + /*[1*/bbb/*1]*/ + /*[2*/ccc/*2]*/;
}
''');
await verify_variables(code);
}
Future<void> test_variable_write() async {
code = TestCode.parse(r'''
void f() {
int aaa = 0, bbb = 0, ccc = 0;
/*[0*/aaa/*0]*/ = 1;
/*[1*/bbb/*1]*/++;
/*[2*/ccc/*2]*/ += 1;
^
}
''');
await verify_variables(code);
}
Future<void> test_variables_scope() async {
// We should not get the top-levels or the nested functions.
code = TestCode.parse(r'''
var aaa = 1;
var bbb = 1;
void f() {
int /*[0*/aaa/*0]*/ = 0, /*[1*/ccc/*1]*/ = 0;
var _ = (aaa, bbb, ccc) => null;
var _ = () {
var aaa = 1, bbb = 1, ccc = 1;
};
^
}
''');
await verify_variables(code);
}
/// Verifies [code] produces the [expected] variables (and only those
/// variables).
Future<void> verify_variables(TestCode code) async {
await initialize();
await openFile(mainFileUri, code.code);
await initialAnalysis;
var actualValues = await getInlineValues(
mainFileUri,
visibleRange: rangeOfWholeContent(code.code),
stoppedAt: code.position.position,
);
var expectedValues = code.ranges.ranges.map(
(range) => InlineValue.t3(
InlineValueVariableLookup(caseSensitiveLookup: true, range: range),
),
);
expect(actualValues, unorderedEquals(expectedValues));
}
}