Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(800)

Unified Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 2754423002: Fail inference when an instance field is referenced. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/summary/link.dart
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 0945db285db9aa2665e25ad4a065d2e5870baef5..43c41d71a839294f274a2719d711e2709ea7e4b6 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -1983,6 +1983,8 @@ class ExprTypeComputer {
int strPtr = 0;
int assignmentOperatorPtr = 0;
+ bool hasError = false;
+
factory ExprTypeComputer(FunctionElementForLink_Local functionElement) {
CompilationUnitElementForLink unit = functionElement.compilationUnit;
LibraryElementForLink library = unit.enclosingElement;
@@ -2047,10 +2049,20 @@ class ExprTypeComputer {
stack.add(DynamicTypeImpl.instance);
break;
case UnlinkedExprOperation.pushReference:
- _doPushReference();
+ try {
+ _doPushReference();
+ } on _InferenceFailedError {
+ hasError = true;
+ return DynamicTypeImpl.instance;
+ }
break;
case UnlinkedExprOperation.extractProperty:
- _doExtractProperty();
+ try {
+ _doExtractProperty();
+ } on _InferenceFailedError {
+ hasError = true;
+ return DynamicTypeImpl.instance;
+ }
break;
case UnlinkedExprOperation.invokeConstructor:
_doInvokeConstructor();
@@ -2133,10 +2145,20 @@ class ExprTypeComputer {
_doConditional();
break;
case UnlinkedExprOperation.assignToRef:
- _doAssignToRef();
+ try {
+ _doAssignToRef();
+ } on _InferenceFailedError {
+ hasError = true;
+ return DynamicTypeImpl.instance;
+ }
break;
case UnlinkedExprOperation.assignToProperty:
- _doAssignToProperty();
+ try {
+ _doAssignToProperty();
+ } on _InferenceFailedError {
+ hasError = true;
+ return DynamicTypeImpl.instance;
+ }
break;
case UnlinkedExprOperation.assignToIndex:
_doAssignToIndex();
@@ -2148,7 +2170,12 @@ class ExprTypeComputer {
_doExtractIndex();
break;
case UnlinkedExprOperation.invokeMethodRef:
- _doInvokeMethodRef();
+ try {
+ _doInvokeMethodRef();
+ } on _InferenceFailedError {
+ hasError = true;
+ return DynamicTypeImpl.instance;
+ }
break;
case UnlinkedExprOperation.invokeMethod:
_doInvokeMethod();
@@ -2235,7 +2262,24 @@ class ExprTypeComputer {
}
}
+ void _throwIfInstanceFieldOrAccessor(Object element) {
+// if (element is NonstaticMemberElementForLink) {
+// element = (element as NonstaticMemberElementForLink).asExecutableElement;
+// }
+ if (element is NonstaticMemberElementForLink &&
+ element.hasInstanceGetterReference ||
+ element is FieldElement && !element.isStatic ||
+ element is PropertyAccessorElement && !element.isStatic) {
+ throw new _InferenceFailedError(
+ 'Instance fields cannot be used for type inference.');
+ }
+ }
+
void _doAssignToProperty() {
+// if (!element.isStatic) {
+ throw new _InferenceFailedError(
+ 'Instance fields cannot be used for type inference.');
+// }
DartType targetType = stack.removeLast();
String propertyName = _getNextString();
UnlinkedExprAssignOperator assignOperator =
@@ -2263,7 +2307,9 @@ class ExprTypeComputer {
}
void _doAssignToRef() {
- refPtr++;
+ EntityRef ref = _getNextRef();
+ ReferenceableElementForLink element = unit.resolveRef(ref.reference);
+ _throwIfInstanceFieldOrAccessor(element);
UnlinkedExprAssignOperator operator =
unlinkedConst.assignmentOperators[assignmentOperatorPtr++];
if (operator == UnlinkedExprAssignOperator.assign) {
@@ -2321,6 +2367,7 @@ class ExprTypeComputer {
ExecutableElement element = target
.lookUpInheritedGetterOrMethod(propertyName, library: library);
if (element != null) {
+ _throwIfInstanceFieldOrAccessor(element);
if (element is PropertyAccessorElement) {
return element.returnType;
} else {
@@ -2436,6 +2483,7 @@ class ExprTypeComputer {
List<DartType> positionalArgTypes = _popList(numPositional);
EntityRef ref = _getNextRef();
ReferenceableElementForLink element = unit.resolveRef(ref.reference);
+ _throwIfInstanceFieldOrAccessor(element);
List<DartType> typeArguments = _getTypeArguments();
stack.add(() {
DartType rawType = element.asStaticType;
@@ -2509,6 +2557,7 @@ class ExprTypeComputer {
// function-typed parameters.
assert(ref.implicitFunctionTypeIndices.isEmpty);
ReferenceableElementForLink element = unit.resolveRef(ref.reference);
+ _throwIfInstanceFieldOrAccessor(element);
stack.add(element.asStaticType);
}
}
@@ -3933,33 +3982,62 @@ class NonstaticMemberElementForLink extends Object
*/
final LibraryElementForLink _library;
+ bool _elementReady = false;
+ ExecutableElement _element;
+
NonstaticMemberElementForLink(this._library, this._target, this._name);
@override
ConstVariableNode get asConstVariable => _target.asConstVariable;
- @override
- DartType get asStaticType {
- if (_library._linker.strongMode) {
+ /**
+ * TODO(scheglov) document
+ */
+ bool get hasInstanceGetterReference {
+ ExecutableElement element = asExecutableElement;
+ if (element is PropertyAccessorElement) {
+ return !element.isStatic;
+ }
+ ReferenceableElementForLink target = _target;
+ if (target is NonstaticMemberElementForLink) {
+ return target.hasInstanceGetterReference;
+ }
+ return false;
+ }
+
+ /**
+ * TODO((scheglov) document
+ */
+ ExecutableElement get asExecutableElement {
+ if (!_elementReady) {
+ _elementReady = true;
DartType targetType = _target.asStaticType;
if (targetType.isDynamic) {
targetType = _library._linker.typeProvider.objectType;
}
if (targetType is InterfaceType) {
- ExecutableElement element =
+ _element =
targetType.lookUpInheritedGetterOrMethod(_name, library: _library);
- if (element != null) {
- if (element is PropertyAccessorElement) {
- return element.returnType;
- } else {
- // Method tear-off
- return element.type;
- }
- }
}
// TODO(paulberry): handle .call on function types and .toString or
// .hashCode on all types.
}
+ return _element;
+ }
+
+ @override
+ DartType get asStaticType {
+ if (_library._linker.strongMode) {
+ ExecutableElement element = asExecutableElement;
+ if (element != null) {
+ if (element is PropertyAccessorElement) {
+ return element.returnType;
+ } else {
+ // Method tear-off
+ return element.type;
+ }
+ }
+ }
return DynamicTypeImpl.instance;
}
@@ -4470,17 +4548,17 @@ class PropertyAccessorElementForLink_Variable extends Object
* progress of type inference.
*/
DartType computeVariableType() {
- if (variable.hasImplicitType &&
- !isStatic &&
- !variable.compilationUnit.isTypeInferenceComplete) {
- // This is an instance field and we are currently inferring types in the
- // library cycle containing it. So we shouldn't use the inferred type
- // (even if we have already computed it), since that would lead to
- // non-deterministic type inference results.
- return DynamicTypeImpl.instance;
- } else {
- return variable.type;
- }
+// if (variable.hasImplicitType &&
+// !isStatic &&
+// !variable.compilationUnit.isTypeInferenceComplete) {
+// // This is an instance field and we are currently inferring types in the
+// // library cycle containing it. So we shouldn't use the inferred type
+// // (even if we have already computed it), since that would lead to
+// // non-deterministic type inference results.
+// return DynamicTypeImpl.instance;
+// } else {
+ return variable.type;
+// }
}
@override
@@ -4739,6 +4817,11 @@ class TypeInferenceNode extends Node<TypeInferenceNode> {
*/
final FunctionElementForLink_Local functionElement;
+ /**
+ * TODO(scheglov) document
+ */
+ bool _hasError = false;
+
TypeInferenceNode(this.functionElement);
@override
@@ -4776,8 +4859,19 @@ class TypeInferenceNode extends Node<TypeInferenceNode> {
EntityRef ref = unlinkedConst.references[refPtr++];
// TODO(paulberry): cache these resolved references for
// later use by evaluate().
- TypeInferenceNode dependency =
- compilationUnit.resolveRef(ref.reference).asTypeInferenceNode;
+ ReferenceableElementForLink element =
+ compilationUnit.resolveRef(ref.reference);
+// // Type inference using instance fields is not allowed.
+// // So, we need to report an error and fail the inference.
+// if (element is VariableElementForLink) {
+// var variable = element as VariableElementForLink;
+// if (!variable.isStatic) {
+// _hasError = true;
+// dependencies.clear();
+// return;
+// }
+// }
+ TypeInferenceNode dependency = element.asTypeInferenceNode;
if (dependency != null) {
dependencies.add(dependency);
}
@@ -4847,18 +4941,23 @@ class TypeInferenceNode extends Node<TypeInferenceNode> {
if (inCycle) {
functionElement._setInferredType(DynamicTypeImpl.instance);
} else {
- var bodyType = new ExprTypeComputer(functionElement).compute();
- if (functionElement.isAsynchronous) {
- var linker = functionElement.compilationUnit.library._linker;
- var typeProvider = linker.typeProvider;
- var typeSystem = linker.typeSystem;
- if (bodyType.isDartAsyncFutureOr) {
- bodyType = (bodyType as InterfaceType).typeArguments[0];
+ var computer = new ExprTypeComputer(functionElement);
+ if (computer.hasError) {
+ functionElement._setInferredType(DynamicTypeImpl.instance);
+ } else {
+ DartType bodyType = computer.compute();
+ if (functionElement.isAsynchronous) {
+ var linker = functionElement.compilationUnit.library._linker;
+ var typeProvider = linker.typeProvider;
+ var typeSystem = linker.typeSystem;
+ if (bodyType.isDartAsyncFutureOr) {
+ bodyType = (bodyType as InterfaceType).typeArguments[0];
+ }
+ bodyType = typeProvider.futureType
+ .instantiate([bodyType.flattenFutures(typeSystem)]);
}
- bodyType = typeProvider.futureType
- .instantiate([bodyType.flattenFutures(typeSystem)]);
+ functionElement._setInferredType(bodyType);
}
- functionElement._setInferredType(bodyType);
}
}
@@ -5190,3 +5289,12 @@ abstract class VariableElementForLink
@override
String toString() => '$enclosingElement.$name';
}
+
+/**
+ * TODO(scheglov) document
+ */
+class _InferenceFailedError {
+ final String message;
+
+ _InferenceFailedError(this.message);
+}

Powered by Google App Engine
This is Rietveld 408576698