ae0a4d994e
This CL introduces new Factory/TypeInferenceListener methods to communicate details about types that are literally named in the source code. Previously, when an expression like `x as List<int>` was analyzed, the resolution information about `List<int>` was communicated to the analyzer via a kernel DartType, forcing the analyzer to walk the type representation, applying each of its constituent parts to the corresponding part of the AST for `List<int>`. This was a lot of work for the analyzer, it failed to resolve parts of invalid types (such as `List<int, String>), and it didn't pave the way toward moving to the Factory API. The new approach is for information about each type appearing in the syntax to be communicated to the analyzer at the time the BodyBuilder converts it to a DartType. So for an invalid type like `List<int, String>`, the resolution of `String` is communicated to the analyzer at the time it is converted to a DartType; later, when `String` is discarded (because `List` only accepts one type parameter), no crucial information is lost, because the analyzer already knows the resolution of `String`. Work still to be done has been captured in issues: - #33844: References to type parameter elements are not translated - #33845: Function typed formal parameters are not handled - #33846: Function types using `Function` syntax are not yet handled Change-Id: I96dd9b6f3eb573b0b7a46335e8644c59fb78bae7 Reviewed-on: https://dart-review.googlesource.com/64262 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
136 lines
3.9 KiB
Dart
136 lines
3.9 KiB
Dart
// Copyright (c) 2017, 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/hint_codes.dart';
|
|
import 'package:analyzer/src/generated/source.dart';
|
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|
|
|
import 'non_hint_code_driver_test.dart';
|
|
|
|
main() {
|
|
defineReflectiveSuite(() {
|
|
defineReflectiveTests(NonHintCodeTest_Kernel);
|
|
});
|
|
}
|
|
|
|
/// Tests marked with this annotation fail because they test features that
|
|
/// were implemented in Analyzer, but are intentionally not included into
|
|
/// the Dart 2.0 plan, or disabled for Dart 2.0 altogether.
|
|
const notForDart2 = const Object();
|
|
|
|
/// Tests marked with this annotations fail because we either have not triaged
|
|
/// them, or know that this is an analyzer problem.
|
|
const potentialAnalyzerProblem = const Object();
|
|
|
|
/// Tests marked with this annotation fail because of a Fasta problem.
|
|
class FastaProblem {
|
|
const FastaProblem(String issueUri);
|
|
}
|
|
|
|
@reflectiveTest
|
|
class NonHintCodeTest_Kernel extends NonHintCodeTest_Driver {
|
|
@override
|
|
bool get enableKernelDriver => true;
|
|
|
|
@override
|
|
bool get useCFE => true;
|
|
|
|
@override
|
|
@failingTest
|
|
test_overrideOnNonOverridingField_inInterface() {
|
|
// Expected 1 errors of type
|
|
// StrongModeCode.STRONG_MODE_INVALID_METHOD_OVERRIDE, found 0
|
|
return super.test_overrideOnNonOverridingField_inInterface();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
test_overrideOnNonOverridingField_inSuperclass() {
|
|
// Expected 1 errors of type
|
|
// StrongModeCode.STRONG_MODE_INVALID_METHOD_OVERRIDE, found 0
|
|
return super.test_overrideOnNonOverridingField_inSuperclass();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
test_propagatedFieldType() {
|
|
// Failed to resolve 1 nodes
|
|
return super.test_propagatedFieldType();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
@notForDart2
|
|
test_undefinedOperator_binaryExpression_inSubtype() async {
|
|
await super.test_undefinedOperator_binaryExpression_inSubtype();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
@notForDart2
|
|
test_undefinedOperator_indexBoth_inSubtype() async {
|
|
await super.test_undefinedOperator_indexBoth_inSubtype();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
@notForDart2
|
|
test_undefinedOperator_indexGetter_inSubtype() async {
|
|
await super.test_undefinedOperator_indexGetter_inSubtype();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
@notForDart2
|
|
test_undefinedOperator_indexSetter_inSubtype() async {
|
|
await super.test_undefinedOperator_indexSetter_inSubtype();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
test_unnecessaryCast_function() {
|
|
// NoSuchMethodError: The getter 'isBottom' was called on null.
|
|
return super.test_unnecessaryCast_function();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
test_unnecessaryCast_function2() {
|
|
// NoSuchMethodError: The getter 'isBottom' was called on null.
|
|
return super.test_unnecessaryCast_function2();
|
|
}
|
|
|
|
@override
|
|
test_unnecessaryCast_generics() async {
|
|
// dartbug.com/18953
|
|
// Overridden because type inference now produces more information and there
|
|
// should now be a hint, where there wasn't one before.
|
|
Source source = addSource(r'''
|
|
import 'dart:async';
|
|
Future<int> f() => new Future.value(0);
|
|
void g(bool c) {
|
|
(c ? f(): new Future.value(0) as Future<int>).then((int value) {});
|
|
}''');
|
|
await computeAnalysisResult(source);
|
|
assertErrors(source, [HintCode.UNNECESSARY_CAST]);
|
|
verify([source]);
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
@potentialAnalyzerProblem
|
|
test_unusedImport_annotationOnDirective() async {
|
|
// Expected 0 errors of type HintCode.UNUSED_IMPORT, found 1 (23)
|
|
await super.test_unusedImport_annotationOnDirective();
|
|
}
|
|
|
|
@override
|
|
@failingTest
|
|
@FastaProblem('https://github.com/dart-lang/sdk/issues/33678')
|
|
test_withSuperMixin() async {
|
|
// Expected 0 errors of type StaticTypeWarningCode.UNDEFINED_SUPER_GETTER, found 1 (82)
|
|
await super.test_withSuperMixin();
|
|
}
|
|
}
|