blob: 84e8cfa98c48b744748b887fd8fce079ff7e2aa0 [file] [log] [blame]
// Copyright (c) 2020, 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:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(FunctionDeclarationResolutionTest);
});
}
@reflectiveTest
class FunctionDeclarationResolutionTest extends PubPackageResolutionTest {
test_asyncGenerator_blockBody_return() async {
await assertErrorsInCode('''
import 'dart:async';
Stream<int> f() async* {
return 0;
}
''', [
error(CompileTimeErrorCode.RETURN_IN_GENERATOR, 49, 6),
]);
var node = findNode.singleFunctionDeclaration;
assertResolvedNodeText(node, r'''
FunctionDeclaration
returnType: NamedType
name: Stream
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::<fragment>::@class::int
type: int
rightBracket: >
element: dart:async::@fragment::dart:async/stream.dart::@class::Stream
type: Stream<int>
name: f
functionExpression: FunctionExpression
parameters: FormalParameterList
leftParenthesis: (
rightParenthesis: )
body: BlockFunctionBody
keyword: async
star: *
block: Block
leftBracket: {
statements
ReturnStatement
returnKeyword: return
expression: IntegerLiteral
literal: 0
staticType: int
semicolon: ;
rightBracket: }
declaredElement: <testLibraryFragment>::@function::f
type: Stream<int> Function()
staticType: Stream<int> Function()
declaredElement: <testLibraryFragment>::@function::f
type: Stream<int> Function()
''');
}
test_asyncGenerator_expressionBody() async {
await assertErrorsInCode('''
import 'dart:async';
Stream<int> f() async* => 0;
''', [
error(CompileTimeErrorCode.RETURN_IN_GENERATOR, 45, 2),
]);
var node = findNode.singleFunctionDeclaration;
assertResolvedNodeText(node, r'''
FunctionDeclaration
returnType: NamedType
name: Stream
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::<fragment>::@class::int
type: int
rightBracket: >
element: dart:async::@fragment::dart:async/stream.dart::@class::Stream
type: Stream<int>
name: f
functionExpression: FunctionExpression
parameters: FormalParameterList
leftParenthesis: (
rightParenthesis: )
body: ExpressionFunctionBody
keyword: async
star: *
functionDefinition: =>
expression: IntegerLiteral
literal: 0
staticType: int
semicolon: ;
declaredElement: <testLibraryFragment>::@function::f
type: Stream<int> Function()
staticType: Stream<int> Function()
declaredElement: <testLibraryFragment>::@function::f
type: Stream<int> Function()
''');
}
test_formalParameterScope_defaultValue() async {
await assertNoErrorsInCode('''
const foo = 0;
void bar([int foo = foo + 1]) {
}
''');
assertElement(
findNode.simple('foo + 1'),
findElement.topGet('foo'),
);
}
test_formalParameterScope_type() async {
await assertNoErrorsInCode('''
class a {}
void bar(a a) {
a;
}
''');
assertElement(
findNode.namedType('a a'),
findElement.class_('a'),
);
assertElement(
findNode.simple('a;'),
findElement.parameter('a'),
);
}
test_getter_formalParameters() async {
await assertErrorsInCode('''
int get foo(double a) => 0;
''', [
error(ParserErrorCode.GETTER_WITH_PARAMETERS, 11, 1),
]);
var node = findNode.singleFunctionDeclaration;
assertResolvedNodeText(node, r'''
FunctionDeclaration
returnType: NamedType
name: int
element: dart:core::<fragment>::@class::int
type: int
propertyKeyword: get
name: foo
functionExpression: FunctionExpression
parameters: FormalParameterList
leftParenthesis: (
parameter: SimpleFormalParameter
type: NamedType
name: double
element: dart:core::<fragment>::@class::double
type: double
name: a
declaredElement: <testLibraryFragment>::@getter::foo::@parameter::a
type: double
rightParenthesis: )
body: ExpressionFunctionBody
functionDefinition: =>
expression: IntegerLiteral
literal: 0
staticType: int
semicolon: ;
declaredElement: <testLibraryFragment>::@getter::foo
type: int Function(double)
staticType: int Function(double)
declaredElement: <testLibraryFragment>::@getter::foo
type: int Function(double)
''');
}
test_syncGenerator_blockBody_return() async {
await assertErrorsInCode('''
Iterable<int> f() sync* {
return 0;
}
''', [
error(CompileTimeErrorCode.RETURN_IN_GENERATOR, 28, 6),
]);
var node = findNode.singleFunctionDeclaration;
assertResolvedNodeText(node, r'''
FunctionDeclaration
returnType: NamedType
name: Iterable
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::<fragment>::@class::int
type: int
rightBracket: >
element: dart:core::<fragment>::@class::Iterable
type: Iterable<int>
name: f
functionExpression: FunctionExpression
parameters: FormalParameterList
leftParenthesis: (
rightParenthesis: )
body: BlockFunctionBody
keyword: sync
star: *
block: Block
leftBracket: {
statements
ReturnStatement
returnKeyword: return
expression: IntegerLiteral
literal: 0
staticType: int
semicolon: ;
rightBracket: }
declaredElement: <testLibraryFragment>::@function::f
type: Iterable<int> Function()
staticType: Iterable<int> Function()
declaredElement: <testLibraryFragment>::@function::f
type: Iterable<int> Function()
''');
}
test_syncGenerator_expressionBody() async {
await assertErrorsInCode('''
Iterable<int> f() sync* => 0;
''', [
error(CompileTimeErrorCode.RETURN_IN_GENERATOR, 24, 2),
]);
var node = findNode.singleFunctionDeclaration;
assertResolvedNodeText(node, r'''
FunctionDeclaration
returnType: NamedType
name: Iterable
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::<fragment>::@class::int
type: int
rightBracket: >
element: dart:core::<fragment>::@class::Iterable
type: Iterable<int>
name: f
functionExpression: FunctionExpression
parameters: FormalParameterList
leftParenthesis: (
rightParenthesis: )
body: ExpressionFunctionBody
keyword: sync
star: *
functionDefinition: =>
expression: IntegerLiteral
literal: 0
staticType: int
semicolon: ;
declaredElement: <testLibraryFragment>::@function::f
type: Iterable<int> Function()
staticType: Iterable<int> Function()
declaredElement: <testLibraryFragment>::@function::f
type: Iterable<int> Function()
''');
}
test_wildCardFunction() async {
await assertErrorsInCode('''
_() {}
''', [
error(WarningCode.UNUSED_ELEMENT, 0, 1),
]);
var node = findNode.singleFunctionDeclaration;
assertResolvedNodeText(node, r'''
FunctionDeclaration
name: _
functionExpression: FunctionExpression
parameters: FormalParameterList
leftParenthesis: (
rightParenthesis: )
body: BlockFunctionBody
block: Block
leftBracket: {
rightBracket: }
declaredElement: <testLibraryFragment>::@function::_
type: dynamic Function()
staticType: dynamic Function()
declaredElement: <testLibraryFragment>::@function::_
type: dynamic Function()
''');
}
test_wildCardFunction_preWildCards() async {
await assertErrorsInCode('''
// @dart = 3.4
// (pre wildcard-variables)
_() {}
''', [
error(WarningCode.UNUSED_ELEMENT, 44, 1),
]);
var node = findNode.singleFunctionDeclaration;
assertResolvedNodeText(node, r'''
FunctionDeclaration
name: _
functionExpression: FunctionExpression
parameters: FormalParameterList
leftParenthesis: (
rightParenthesis: )
body: BlockFunctionBody
block: Block
leftBracket: {
rightBracket: }
declaredElement: <testLibraryFragment>::@function::_
type: dynamic Function()
staticType: dynamic Function()
declaredElement: <testLibraryFragment>::@function::_
type: dynamic Function()
''');
}
test_wildcardFunctionTypeParameter() async {
// Corresponding language test:
// language/wildcard_variables/multiple/local_declaration_type_parameter_error_test
await assertErrorsInCode(r'''
void f<_ extends void Function<_>(_, _), _>() {}
''', [
error(CompileTimeErrorCode.UNDEFINED_CLASS, 34, 1),
error(CompileTimeErrorCode.UNDEFINED_CLASS, 37, 1),
]);
var node = findNode.typeParameter('<_>');
assertResolvedNodeText(node, r'''
TypeParameter
name: _
extendsKeyword: extends
bound: GenericFunctionType
returnType: NamedType
name: void
element: <null>
type: void
functionKeyword: Function
typeParameters: TypeParameterList
leftBracket: <
typeParameters
TypeParameter
name: _
declaredElement: _@31
rightBracket: >
parameters: FormalParameterList
leftParenthesis: (
parameter: SimpleFormalParameter
type: NamedType
name: _
element: <null>
type: InvalidType
declaredElement: @-1
type: InvalidType
parameter: SimpleFormalParameter
type: NamedType
name: _
element: <null>
type: InvalidType
declaredElement: @-1
type: InvalidType
rightParenthesis: )
declaredElement: GenericFunctionTypeElement
parameters
<empty>
kind: required positional
type: InvalidType
<empty>
kind: required positional
type: InvalidType
returnType: void
type: void Function<_>(InvalidType, InvalidType)
type: void Function<_>(InvalidType, InvalidType)
declaredElement: _@7
''');
}
}