// 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 'dart:async'; import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/src/dart/analysis/driver.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../src/dart/resolution/driver_resolution.dart'; main() { defineReflectiveSuite(() { if (AnalysisDriver.useSummary2) { defineReflectiveTests(InvalidCodeSummary2Test); } else { defineReflectiveTests(InvalidCodeTest); } defineReflectiveTests(InvalidCodeWithExtensionMethodsTest); }); } @reflectiveTest class InvalidCodeSummary2Test extends InvalidCodeTest { @failingTest test_fuzz_12() { return test_fuzz_12(); } } /// Tests for various end-to-end cases when invalid code caused exceptions /// in one or another Analyzer subsystem. We are not interested not in specific /// errors generated, but we want to make sure that there is at least one, /// and analysis finishes without exceptions. @reflectiveTest class InvalidCodeTest extends DriverResolutionTest { /// This code results in a method with the empty name, and the default /// constructor, which also has the empty name. The `Map` in `f` initializer /// references the empty name. test_constructorAndMethodNameCollision() async { await _assertCanBeAnalyzed(''' class C { var f = { : }; @ (); } '''); } test_constructorDeclaration_named_missingName() async { await _assertCanBeAnalyzed(''' class C { C.(); } '''); } test_constructorDeclaration_named_missingName_factory() async { await _assertCanBeAnalyzed(''' class C { factory C.(); } '''); } test_fuzz_01() async { await _assertCanBeAnalyzed(r''' typedef F = void Function(bool, int a(double b)); '''); var function = findElement.genericTypeAlias('F').function; assertElementTypeString( function.type, 'void Function(bool, int Function(double))', ); } test_fuzz_02() async { await _assertCanBeAnalyzed(r''' class G(e await _assertCanBeAnalyzed(r''' typedef F(a(e)); '''); } test_fuzz_08() async { // class{const v // v=((){try catch // When we resolve initializers of typed constant variables, // we should build locale elements. await _assertCanBeAnalyzed(r''' class C { const Object v = () { var a = 0; }; } '''); } test_fuzz_09() async { await _assertCanBeAnalyzed(r''' typedef void F(int a, this.b); '''); var function = findElement.genericTypeAlias('F').function; assertElementTypeString( function.type, 'void Function(int, dynamic)', ); } test_fuzz_10() async { await _assertCanBeAnalyzed(r''' void f<@A(() { Function() v; }) T>() {} '''); } test_fuzz_11() async { // Here `F` is a generic function, so it cannot be used as a bound for // a type parameter. The reason it crashed was that we did not build // the bound for `Y` (not `T`), because of the order in which types // for `T extends F` and `typedef F` were built. await _assertCanBeAnalyzed(r''' typedef F = void Function(); class A {} '''); } test_fuzz_12() async { // This code crashed with summary2 because usually AST reader is lazy, // so we did not read metadata `@b` for `c`. But default values must be // read fully. await _assertCanBeAnalyzed(r''' void f({a = [for (@b c = 0;;)]}) {} '''); } test_fuzz_13() async { // `x is int` promotes the type of `x` to `S extends int`, and the // underlying element is `TypeParameterMember`, which by itself is // questionable. But this is not a valid constant anyway, so we should // not even try to serialize it. await _assertCanBeAnalyzed(r''' const v = [(S x) => x is int ? x : 0]; '''); } test_genericFunction_asTypeArgument_ofUnresolvedClass() async { await _assertCanBeAnalyzed(r''' C c; '''); } test_keywordInConstructorInitializer_assert() async { await _assertCanBeAnalyzed(''' class C { C() : assert = 0; } '''); } test_keywordInConstructorInitializer_null() async { await _assertCanBeAnalyzed(''' class C { C() : null = 0; } '''); } test_keywordInConstructorInitializer_super() async { await _assertCanBeAnalyzed(''' class C { C() : super = 0; } '''); } test_keywordInConstructorInitializer_this() async { await _assertCanBeAnalyzed(''' class C { C() : this = 0; } '''); } Future _assertCanBeAnalyzed(String text) async { addTestFile(text); await resolveTestFile(); assertHasTestErrors(); } } @reflectiveTest class InvalidCodeWithExtensionMethodsTest extends DriverResolutionTest { @override AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl() ..contextFeatures = new FeatureSet.forTesting( sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]); test_fuzz_14() async { // This crashes because parser produces `ConstructorDeclaration`. // So, we try to create `ConstructorElement` for it, and it wants // `ClassElement` as the enclosing element. But we have `ExtensionElement`. await _assertCanBeAnalyzed(r''' extension E { factory S() {} } '''); } Future _assertCanBeAnalyzed(String text) async { addTestFile(text); await resolveTestFile(); assertHasTestErrors(); } }