mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:26:38 +00:00
Issue 33506. Rewrite MethodInvocation into InstanceCreationExpression.
R=brianwilkerson@google.com, paulberry@google.com Change-Id: I712ab3c79cfe29b2c201b0affc10b33fc0f60d15 Bug: https://github.com/dart-lang/sdk/issues/33506 Reviewed-on: https://dart-review.googlesource.com/68004 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
26e087e66b
commit
d6189709b8
|
@ -633,14 +633,4 @@ class AnalysisHoverTest_UseCFE extends AnalysisHoverTest {
|
|||
@override
|
||||
test_instanceCreation_implicit_withTypeArgument() async =>
|
||||
super.test_instanceCreation_implicit_withTypeArgument();
|
||||
|
||||
@failingTest
|
||||
@override
|
||||
test_instanceCreation_noKeyword_const() async =>
|
||||
super.test_instanceCreation_noKeyword_const();
|
||||
|
||||
@failingTest
|
||||
@override
|
||||
test_instanceCreation_noKeyword_new() async =>
|
||||
super.test_instanceCreation_noKeyword_new();
|
||||
}
|
||||
|
|
|
@ -734,13 +734,6 @@ class LibraryAnalyzer {
|
|||
new DeclarationResolver(enableKernelDriver: true, applyKernelTypes: true)
|
||||
.resolve(unit, unitElement);
|
||||
|
||||
// TODO(paulberry): need to find a better way to do this.
|
||||
// See dartbug.com/33506.
|
||||
// if (_libraryElement.context.analysisOptions.previewDart2) {
|
||||
// unit.accept(new AstRewriteVisitor(_context.typeSystem, _libraryElement,
|
||||
// file.source, _typeProvider, AnalysisErrorListener.NULL_LISTENER));
|
||||
// }
|
||||
|
||||
var applierContext = new _ResolutionApplierContext(_resynthesizer,
|
||||
_typeProvider, _libraryElement, resolution, unit.localDeclarations);
|
||||
var applier = applierContext.applier;
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:analyzer/dart/ast/visitor.dart';
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer/src/dart/ast/ast.dart';
|
||||
import 'package:analyzer/src/dart/ast/utilities.dart';
|
||||
import 'package:analyzer/src/dart/element/element.dart';
|
||||
import 'package:analyzer/src/dart/element/member.dart';
|
||||
import 'package:analyzer/src/fasta/resolution_storer.dart';
|
||||
|
@ -538,6 +539,10 @@ class ResolutionApplier extends GeneralizingAstVisitor {
|
|||
_resolveNamedArguments(argumentList, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
if (invokeElement is ConstructorElement) {
|
||||
_rewriteInfoInstanceCreation(node, invokeElement, invokeType, resultType);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -763,6 +768,65 @@ class ResolutionApplier extends GeneralizingAstVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
/// Rewrite AST if the [node] represents an instance creation.
|
||||
void _rewriteInfoInstanceCreation(
|
||||
MethodInvocation node,
|
||||
ConstructorElement invokeElement,
|
||||
DartType invokeType,
|
||||
DartType resultType) {
|
||||
if (node.isCascaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
Identifier typeIdentifier;
|
||||
Token constructorIdentifierPeriod;
|
||||
SimpleIdentifier constructorIdentifier;
|
||||
var target = node.target;
|
||||
if (target == null) {
|
||||
SimpleIdentifier simpleTypeIdentifier = node.methodName;
|
||||
simpleTypeIdentifier.staticElement = resultType.element;
|
||||
simpleTypeIdentifier.staticType = resultType;
|
||||
|
||||
typeIdentifier = simpleTypeIdentifier;
|
||||
} else if (target is SimpleIdentifier) {
|
||||
if (target.staticElement is PrefixElement) {
|
||||
SimpleIdentifier simpleTypeIdentifier = node.methodName;
|
||||
simpleTypeIdentifier.staticElement = resultType.element;
|
||||
simpleTypeIdentifier.staticType = resultType;
|
||||
|
||||
typeIdentifier = astFactory.prefixedIdentifier(
|
||||
target, node.operator, simpleTypeIdentifier);
|
||||
} else {
|
||||
typeIdentifier = target;
|
||||
|
||||
constructorIdentifierPeriod = node.operator;
|
||||
constructorIdentifier = node.methodName;
|
||||
}
|
||||
} else {
|
||||
PrefixedIdentifier prefixed = target;
|
||||
typeIdentifier = prefixed;
|
||||
|
||||
constructorIdentifierPeriod = prefixed.period;
|
||||
constructorIdentifier = node.methodName;
|
||||
}
|
||||
|
||||
var typeName = astFactory.typeName(typeIdentifier, node.typeArguments);
|
||||
typeName.type = resultType;
|
||||
|
||||
var creation = astFactory.instanceCreationExpression(
|
||||
null,
|
||||
astFactory.constructorName(
|
||||
typeName,
|
||||
constructorIdentifierPeriod,
|
||||
constructorIdentifier,
|
||||
),
|
||||
node.argumentList,
|
||||
);
|
||||
creation.staticElement = invokeElement;
|
||||
creation.staticType = resultType;
|
||||
NodeReplacer.replace(node, creation);
|
||||
}
|
||||
|
||||
void _storeFunctionType(DartType type, FunctionTypedElementImpl element) {
|
||||
if (type is FunctionType && element != null) {
|
||||
DartType Function(DartType) substituteConstituentType;
|
||||
|
|
|
@ -49,6 +49,13 @@ class AnalysisDriverResolutionTest_Kernel extends AnalysisDriverResolutionTest {
|
|||
await super.test_invalid_fieldInitializer_this();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
test_optionalConst_typeArguments() async {
|
||||
// We should get ConstructorMember, but convert to just ConstructorElement.
|
||||
await super.test_optionalConst_typeArguments();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
test_unresolved_assignment_left_indexed1_simple() async {
|
||||
|
|
|
@ -150,8 +150,6 @@ class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest {
|
|||
assertElement(name.identifier, expectedElement);
|
||||
if (useCFE) {
|
||||
assertType(name.identifier, expectedType);
|
||||
} else {
|
||||
expect(name.identifier.staticType, isNull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,6 +191,8 @@ class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest {
|
|||
return node.staticElement;
|
||||
} else if (node is IndexExpression) {
|
||||
return node.staticElement;
|
||||
} else if (node is InstanceCreationExpression) {
|
||||
return node.staticElement;
|
||||
} else if (node is PostfixExpression) {
|
||||
return node.staticElement;
|
||||
} else if (node is PrefixExpression) {
|
||||
|
@ -6716,6 +6716,112 @@ void f<T, U>(T a, U b) {}
|
|||
}
|
||||
}
|
||||
|
||||
test_optionalConst() async {
|
||||
addTestFile(r'''
|
||||
class C {
|
||||
const C();
|
||||
const C.named();
|
||||
}
|
||||
const a = C(); // ref
|
||||
const b = C.named(); // ref
|
||||
''');
|
||||
await resolveTestFile();
|
||||
expect(result.errors, isEmpty);
|
||||
var c = findElement.class_('C');
|
||||
|
||||
{
|
||||
var creation = findNode.instanceCreation('C(); // ref');
|
||||
assertElement(creation, c.unnamedConstructor);
|
||||
assertType(creation, 'C');
|
||||
|
||||
assertTypeName(creation.constructorName.type, c, 'C');
|
||||
}
|
||||
|
||||
{
|
||||
var creation = findNode.instanceCreation('C.named(); // ref');
|
||||
var namedConstructor = c.getNamedConstructor('named');
|
||||
assertElement(creation, namedConstructor);
|
||||
assertType(creation, 'C');
|
||||
|
||||
assertTypeName(creation.constructorName.type, c, 'C');
|
||||
assertElement(creation.constructorName.name, namedConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
test_optionalConst_prefixed() async {
|
||||
provider.newFile(_p('/test/lib/a.dart'), r'''
|
||||
class C {
|
||||
const C();
|
||||
const C.named();
|
||||
}
|
||||
''');
|
||||
addTestFile(r'''
|
||||
import 'a.dart' as p;
|
||||
const a = p.C(); // ref
|
||||
const b = p.C.named(); // ref
|
||||
''');
|
||||
await resolveTestFile();
|
||||
expect(result.errors, isEmpty);
|
||||
var import = findElement.import('package:test/a.dart');
|
||||
var c = import.importedLibrary.getType('C');
|
||||
|
||||
{
|
||||
var creation = findNode.instanceCreation('C(); // ref');
|
||||
assertElement(creation, c.unnamedConstructor);
|
||||
assertType(creation, 'C');
|
||||
|
||||
assertTypeName(creation.constructorName.type, c, 'C',
|
||||
expectedPrefix: import.prefix);
|
||||
}
|
||||
|
||||
{
|
||||
var creation = findNode.instanceCreation('C.named(); // ref');
|
||||
var namedConstructor = c.getNamedConstructor('named');
|
||||
assertElement(creation, namedConstructor);
|
||||
assertType(creation, 'C');
|
||||
|
||||
assertTypeName(creation.constructorName.type, c, 'C',
|
||||
expectedPrefix: import.prefix);
|
||||
assertElement(creation.constructorName.name, namedConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
test_optionalConst_typeArguments() async {
|
||||
addTestFile(r'''
|
||||
class C<T> {
|
||||
const C();
|
||||
const C.named();
|
||||
}
|
||||
const a = C<int>(); // ref
|
||||
const b = C<String>.named(); // ref
|
||||
''');
|
||||
await resolveTestFile();
|
||||
expect(result.errors, isEmpty);
|
||||
var c = findElement.class_('C');
|
||||
|
||||
{
|
||||
var creation = findNode.instanceCreation('C<int>(); // ref');
|
||||
assertMember(creation, 'C<int>', c.unnamedConstructor);
|
||||
assertType(creation, 'C<int>');
|
||||
|
||||
assertTypeName(creation.constructorName.type, c, 'C<int>');
|
||||
assertTypeName(findNode.typeName('int>'), intElement, 'int');
|
||||
}
|
||||
|
||||
{
|
||||
var creation = findNode.instanceCreation('C<String>.named(); // ref');
|
||||
var namedConstructor = c.getNamedConstructor('named');
|
||||
assertMember(creation, 'C<String>', namedConstructor);
|
||||
assertType(creation, 'C<String>');
|
||||
|
||||
assertTypeName(creation.constructorName.type, c, 'C<String>');
|
||||
assertTypeName(findNode.typeName('String>'), stringElement, 'String');
|
||||
|
||||
assertMember(
|
||||
creation.constructorName.name, 'C<String>', namedConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
test_outline_invalid_mixin_arguments_tooFew() async {
|
||||
addTestFile(r'''
|
||||
class A extends Object with Map<int> {}
|
||||
|
|
Loading…
Reference in a new issue