Issue 28550. Fix for resynthesizing invalid elements as declared types.

R=paulberry@google.com
BUG= https://github.com/dart-lang/sdk/issues/28550

Review-Url: https://codereview.chromium.org/2665013002 .
This commit is contained in:
Konstantin Shcheglov 2017-01-31 09:26:31 -08:00
parent a7ffe24177
commit b8aca22c6a
5 changed files with 63 additions and 17 deletions

View file

@ -74,7 +74,7 @@ class AnalysisDriver {
/**
* The version of data format, should be incremented on every format change.
*/
static const int DATA_VERSION = 15;
static const int DATA_VERSION = 16;
/**
* The number of exception contexts allowed to write. Once this field is

View file

@ -3871,7 +3871,8 @@ abstract class ExecutableElementImpl extends ElementImpl
serializedExecutable.inferredReturnTypeSlot, typeParameterContext);
_declaredReturnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
serializedExecutable.returnType, typeParameterContext,
defaultVoid: isSetter && context.analysisOptions.strongMode);
defaultVoid: isSetter && context.analysisOptions.strongMode,
declaredType: true);
}
return _returnType ?? _declaredReturnType;
}
@ -4743,8 +4744,9 @@ class FunctionTypeAliasElementImpl extends ElementImpl
@override
DartType get returnType {
if (_unlinkedTypedef != null && _returnType == null) {
_returnType = enclosingUnit.resynthesizerContext
.resolveTypeRef(_unlinkedTypedef.returnType, this);
_returnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedTypedef.returnType, this,
declaredType: true);
}
return _returnType;
}
@ -6890,8 +6892,9 @@ abstract class NonParameterVariableElementImpl extends VariableElementImpl {
if (_unlinkedVariable != null && _declaredType == null && _type == null) {
_type = enclosingUnit.resynthesizerContext.resolveLinkedType(
_unlinkedVariable.inferredTypeSlot, typeParameterContext);
_declaredType = enclosingUnit.resynthesizerContext
.resolveTypeRef(_unlinkedVariable.type, typeParameterContext);
_declaredType = enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedVariable.type, typeParameterContext,
declaredType: true);
}
return super.type;
}
@ -7379,8 +7382,9 @@ class ParameterElementImpl extends VariableElementImpl
} else {
_type = enclosingUnit.resynthesizerContext.resolveLinkedType(
_unlinkedParam.inferredTypeSlot, typeParameterContext);
_declaredType = enclosingUnit.resynthesizerContext
.resolveTypeRef(_unlinkedParam.type, typeParameterContext);
_declaredType = enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedParam.type, typeParameterContext,
declaredType: true);
}
}
}
@ -7955,7 +7959,9 @@ abstract class ResynthesizerContext {
*/
DartType resolveTypeRef(
EntityRef type, TypeParameterizedElementMixin typeParameterContext,
{bool defaultVoid: false, bool instantiateToBoundsAllowed: true});
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false});
}
/**
@ -8155,7 +8161,7 @@ class TypeParameterElementImpl extends ElementImpl
}
return _bound ??= enclosingUnit.resynthesizerContext.resolveTypeRef(
_unlinkedTypeParam.bound, enclosingElement,
instantiateToBoundsAllowed: false);
instantiateToBoundsAllowed: false, declaredType: true);
}
return _bound;
}

View file

@ -1061,7 +1061,9 @@ abstract class CompilationUnitElementForLink
@override
DartType resolveTypeRef(
EntityRef type, TypeParameterizedElementMixin typeParameterContext,
{bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) {
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
if (type == null) {
if (defaultVoid) {
return VoidTypeImpl.instance;

View file

@ -1193,6 +1193,11 @@ class _ReferenceInfo {
*/
final String name;
/**
* Is `true` if the [element] can be used as a declared type.
*/
final bool isDeclarableType;
/**
* The element referred to by this reference, or `null` if there is no
* associated element (e.g. because it is a reference to an undefined
@ -1221,8 +1226,14 @@ class _ReferenceInfo {
* the type itself. Otherwise, pass `null` and the type will be computed
* when appropriate.
*/
_ReferenceInfo(this.libraryResynthesizer, this.enclosing, this.name,
this.element, DartType specialType, this.numTypeParameters) {
_ReferenceInfo(
this.libraryResynthesizer,
this.enclosing,
this.name,
this.isDeclarableType,
this.element,
DartType specialType,
this.numTypeParameters) {
if (specialType != null) {
type = specialType;
} else {
@ -1409,10 +1420,13 @@ class _ResynthesizerContext implements ResynthesizerContext {
@override
DartType resolveTypeRef(
EntityRef type, TypeParameterizedElementMixin typeParameterContext,
{bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) {
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
return _unitResynthesizer.buildType(type, typeParameterContext,
defaultVoid: defaultVoid,
instantiateToBoundsAllowed: instantiateToBoundsAllowed);
instantiateToBoundsAllowed: instantiateToBoundsAllowed,
declaredType: declaredType);
}
}
@ -1592,7 +1606,9 @@ class _UnitResynthesizer {
*/
DartType buildType(
EntityRef type, TypeParameterizedElementMixin typeParameterContext,
{bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) {
{bool defaultVoid: false,
bool instantiateToBoundsAllowed: true,
bool declaredType: false}) {
if (type == null) {
if (defaultVoid) {
return VoidTypeImpl.instance;
@ -1616,6 +1632,9 @@ class _UnitResynthesizer {
}
_ReferenceInfo referenceInfo = getReferenceInfo(type.reference);
if (declaredType && !referenceInfo.isDeclarableType) {
return DynamicTypeImpl.instance;
}
return referenceInfo.buildType(
instantiateToBoundsAllowed,
type.typeArguments.length,
@ -1715,19 +1734,24 @@ class _UnitResynthesizer {
: null;
Element element;
DartType type;
bool isDeclarableType = false;
int numTypeParameters = linkedReference.numTypeParameters;
if (linkedReference.kind == ReferenceKind.unresolved) {
type = UndefinedTypeImpl.instance;
element = null;
isDeclarableType = true;
} else if (name == 'dynamic') {
type = DynamicTypeImpl.instance;
element = type.element;
isDeclarableType = true;
} else if (name == 'void') {
type = VoidTypeImpl.instance;
element = type.element;
isDeclarableType = true;
} else if (name == '*bottom*') {
type = BottomTypeImpl.instance;
element = null;
isDeclarableType = true;
} else {
List<String> locationComponents;
if (enclosingInfo != null && enclosingInfo.element is ClassElement) {
@ -1756,6 +1780,7 @@ class _UnitResynthesizer {
switch (linkedReference.kind) {
case ReferenceKind.classOrEnum:
element = new ClassElementHandle(summaryResynthesizer, location);
isDeclarableType = true;
break;
case ReferenceKind.constructor:
assert(location.components.length == 4);
@ -1782,6 +1807,7 @@ class _UnitResynthesizer {
case ReferenceKind.typedef:
element = new FunctionTypeAliasElementHandle(
summaryResynthesizer, location);
isDeclarableType = true;
break;
case ReferenceKind.variable:
Element enclosingElement = enclosingInfo.element;
@ -1811,7 +1837,7 @@ class _UnitResynthesizer {
}
}
result = new _ReferenceInfo(libraryResynthesizer, enclosingInfo, name,
element, type, numTypeParameters);
isDeclarableType, element, type, numTypeParameters);
referenceInfos[index] = result;
}
return result;

View file

@ -4659,6 +4659,18 @@ bool f() => true;
checkLibrary('dynamic d;');
}
test_type_invalid_topLevelVariableElement_asType() {
checkLibrary(
'''
class C<T extends V> {}
typedef V F(V p);
V f(V p) {}
V V2 = null;
int V = 0;
''',
allowErrors: true);
}
test_type_invalid_typeParameter_asPrefix() {
checkLibrary(
'''