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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * This library is capable of producing linked summaries from unlinked 6 * This library is capable of producing linked summaries from unlinked
7 * ones (or prelinked ones). It functions by building a miniature 7 * ones (or prelinked ones). It functions by building a miniature
8 * element model to represent the contents of the summaries, and then 8 * element model to represent the contents of the summaries, and then
9 * scanning the element model to gather linked information and adding 9 * scanning the element model to gather linked information and adding
10 * it to the summary data structures. 10 * it to the summary data structures.
(...skipping 1965 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 final Linker linker; 1976 final Linker linker;
1977 final TypeProvider typeProvider; 1977 final TypeProvider typeProvider;
1978 final UnlinkedExpr unlinkedConst; 1978 final UnlinkedExpr unlinkedConst;
1979 1979
1980 final List<DartType> stack = <DartType>[]; 1980 final List<DartType> stack = <DartType>[];
1981 int intPtr = 0; 1981 int intPtr = 0;
1982 int refPtr = 0; 1982 int refPtr = 0;
1983 int strPtr = 0; 1983 int strPtr = 0;
1984 int assignmentOperatorPtr = 0; 1984 int assignmentOperatorPtr = 0;
1985 1985
1986 bool hasError = false;
1987
1986 factory ExprTypeComputer(FunctionElementForLink_Local functionElement) { 1988 factory ExprTypeComputer(FunctionElementForLink_Local functionElement) {
1987 CompilationUnitElementForLink unit = functionElement.compilationUnit; 1989 CompilationUnitElementForLink unit = functionElement.compilationUnit;
1988 LibraryElementForLink library = unit.enclosingElement; 1990 LibraryElementForLink library = unit.enclosingElement;
1989 Linker linker = library._linker; 1991 Linker linker = library._linker;
1990 TypeProvider typeProvider = linker.typeProvider; 1992 TypeProvider typeProvider = linker.typeProvider;
1991 UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr; 1993 UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr;
1992 return new ExprTypeComputer._( 1994 return new ExprTypeComputer._(
1993 functionElement, unit, library, linker, typeProvider, unlinkedConst); 1995 functionElement, unit, library, linker, typeProvider, unlinkedConst);
1994 } 1996 }
1995 1997
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 case UnlinkedExprOperation.pushNull: 2042 case UnlinkedExprOperation.pushNull:
2041 stack.add(typeProvider.nullType); 2043 stack.add(typeProvider.nullType);
2042 break; 2044 break;
2043 case UnlinkedExprOperation.pushSuper: 2045 case UnlinkedExprOperation.pushSuper:
2044 stack.add(DynamicTypeImpl.instance); 2046 stack.add(DynamicTypeImpl.instance);
2045 break; 2047 break;
2046 case UnlinkedExprOperation.pushThis: 2048 case UnlinkedExprOperation.pushThis:
2047 stack.add(DynamicTypeImpl.instance); 2049 stack.add(DynamicTypeImpl.instance);
2048 break; 2050 break;
2049 case UnlinkedExprOperation.pushReference: 2051 case UnlinkedExprOperation.pushReference:
2050 _doPushReference(); 2052 try {
2053 _doPushReference();
2054 } on _InferenceFailedError {
2055 hasError = true;
2056 return DynamicTypeImpl.instance;
2057 }
2051 break; 2058 break;
2052 case UnlinkedExprOperation.extractProperty: 2059 case UnlinkedExprOperation.extractProperty:
2053 _doExtractProperty(); 2060 try {
2061 _doExtractProperty();
2062 } on _InferenceFailedError {
2063 hasError = true;
2064 return DynamicTypeImpl.instance;
2065 }
2054 break; 2066 break;
2055 case UnlinkedExprOperation.invokeConstructor: 2067 case UnlinkedExprOperation.invokeConstructor:
2056 _doInvokeConstructor(); 2068 _doInvokeConstructor();
2057 break; 2069 break;
2058 case UnlinkedExprOperation.makeUntypedList: 2070 case UnlinkedExprOperation.makeUntypedList:
2059 _doMakeUntypedList(); 2071 _doMakeUntypedList();
2060 break; 2072 break;
2061 case UnlinkedExprOperation.makeUntypedMap: 2073 case UnlinkedExprOperation.makeUntypedMap:
2062 _doMakeUntypedMap(); 2074 _doMakeUntypedMap();
2063 break; 2075 break;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2126 case UnlinkedExprOperation.lessEqual: 2138 case UnlinkedExprOperation.lessEqual:
2127 _computeBinaryExpressionType(TokenType.LT_EQ); 2139 _computeBinaryExpressionType(TokenType.LT_EQ);
2128 break; 2140 break;
2129 case UnlinkedExprOperation.modulo: 2141 case UnlinkedExprOperation.modulo:
2130 _computeBinaryExpressionType(TokenType.PERCENT); 2142 _computeBinaryExpressionType(TokenType.PERCENT);
2131 break; 2143 break;
2132 case UnlinkedExprOperation.conditional: 2144 case UnlinkedExprOperation.conditional:
2133 _doConditional(); 2145 _doConditional();
2134 break; 2146 break;
2135 case UnlinkedExprOperation.assignToRef: 2147 case UnlinkedExprOperation.assignToRef:
2136 _doAssignToRef(); 2148 try {
2149 _doAssignToRef();
2150 } on _InferenceFailedError {
2151 hasError = true;
2152 return DynamicTypeImpl.instance;
2153 }
2137 break; 2154 break;
2138 case UnlinkedExprOperation.assignToProperty: 2155 case UnlinkedExprOperation.assignToProperty:
2139 _doAssignToProperty(); 2156 try {
2157 _doAssignToProperty();
2158 } on _InferenceFailedError {
2159 hasError = true;
2160 return DynamicTypeImpl.instance;
2161 }
2140 break; 2162 break;
2141 case UnlinkedExprOperation.assignToIndex: 2163 case UnlinkedExprOperation.assignToIndex:
2142 _doAssignToIndex(); 2164 _doAssignToIndex();
2143 break; 2165 break;
2144 case UnlinkedExprOperation.await: 2166 case UnlinkedExprOperation.await:
2145 _doAwait(); 2167 _doAwait();
2146 break; 2168 break;
2147 case UnlinkedExprOperation.extractIndex: 2169 case UnlinkedExprOperation.extractIndex:
2148 _doExtractIndex(); 2170 _doExtractIndex();
2149 break; 2171 break;
2150 case UnlinkedExprOperation.invokeMethodRef: 2172 case UnlinkedExprOperation.invokeMethodRef:
2151 _doInvokeMethodRef(); 2173 try {
2174 _doInvokeMethodRef();
2175 } on _InferenceFailedError {
2176 hasError = true;
2177 return DynamicTypeImpl.instance;
2178 }
2152 break; 2179 break;
2153 case UnlinkedExprOperation.invokeMethod: 2180 case UnlinkedExprOperation.invokeMethod:
2154 _doInvokeMethod(); 2181 _doInvokeMethod();
2155 break; 2182 break;
2156 case UnlinkedExprOperation.cascadeSectionBegin: 2183 case UnlinkedExprOperation.cascadeSectionBegin:
2157 stack.add(stack.last); 2184 stack.add(stack.last);
2158 break; 2185 break;
2159 case UnlinkedExprOperation.cascadeSectionEnd: 2186 case UnlinkedExprOperation.cascadeSectionEnd:
2160 stack.removeLast(); 2187 stack.removeLast();
2161 break; 2188 break;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2228 } else if (isIncrementOrDecrement(operator)) { 2255 } else if (isIncrementOrDecrement(operator)) {
2229 // TODO(scheglov) implement 2256 // TODO(scheglov) implement
2230 stack.add(DynamicTypeImpl.instance); 2257 stack.add(DynamicTypeImpl.instance);
2231 } else { 2258 } else {
2232 stack.removeLast(); 2259 stack.removeLast();
2233 // TODO(scheglov) implement 2260 // TODO(scheglov) implement
2234 stack.add(DynamicTypeImpl.instance); 2261 stack.add(DynamicTypeImpl.instance);
2235 } 2262 }
2236 } 2263 }
2237 2264
2265 void _throwIfInstanceFieldOrAccessor(Object element) {
2266 // if (element is NonstaticMemberElementForLink) {
2267 // element = (element as NonstaticMemberElementForLink).asExecutableElement ;
2268 // }
2269 if (element is NonstaticMemberElementForLink &&
2270 element.hasInstanceGetterReference ||
2271 element is FieldElement && !element.isStatic ||
2272 element is PropertyAccessorElement && !element.isStatic) {
2273 throw new _InferenceFailedError(
2274 'Instance fields cannot be used for type inference.');
2275 }
2276 }
2277
2238 void _doAssignToProperty() { 2278 void _doAssignToProperty() {
2279 // if (!element.isStatic) {
2280 throw new _InferenceFailedError(
2281 'Instance fields cannot be used for type inference.');
2282 // }
2239 DartType targetType = stack.removeLast(); 2283 DartType targetType = stack.removeLast();
2240 String propertyName = _getNextString(); 2284 String propertyName = _getNextString();
2241 UnlinkedExprAssignOperator assignOperator = 2285 UnlinkedExprAssignOperator assignOperator =
2242 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; 2286 unlinkedConst.assignmentOperators[assignmentOperatorPtr++];
2243 if (assignOperator == UnlinkedExprAssignOperator.assign) { 2287 if (assignOperator == UnlinkedExprAssignOperator.assign) {
2244 // The type of the assignment is the type of the value, 2288 // The type of the assignment is the type of the value,
2245 // which is already in the stack. 2289 // which is already in the stack.
2246 } else if (assignOperator == UnlinkedExprAssignOperator.postfixDecrement || 2290 } else if (assignOperator == UnlinkedExprAssignOperator.postfixDecrement ||
2247 assignOperator == UnlinkedExprAssignOperator.postfixIncrement) { 2291 assignOperator == UnlinkedExprAssignOperator.postfixIncrement) {
2248 DartType propertyType = _getPropertyType(targetType, propertyName); 2292 DartType propertyType = _getPropertyType(targetType, propertyName);
2249 stack.add(propertyType); 2293 stack.add(propertyType);
2250 } else if (assignOperator == UnlinkedExprAssignOperator.prefixDecrement) { 2294 } else if (assignOperator == UnlinkedExprAssignOperator.prefixDecrement) {
2251 _pushPropertyBinaryExpression( 2295 _pushPropertyBinaryExpression(
2252 targetType, propertyName, TokenType.MINUS, typeProvider.intType); 2296 targetType, propertyName, TokenType.MINUS, typeProvider.intType);
2253 } else if (assignOperator == UnlinkedExprAssignOperator.prefixIncrement) { 2297 } else if (assignOperator == UnlinkedExprAssignOperator.prefixIncrement) {
2254 _pushPropertyBinaryExpression( 2298 _pushPropertyBinaryExpression(
2255 targetType, propertyName, TokenType.PLUS, typeProvider.intType); 2299 targetType, propertyName, TokenType.PLUS, typeProvider.intType);
2256 } else { 2300 } else {
2257 TokenType binaryOperator = 2301 TokenType binaryOperator =
2258 _convertAssignOperatorToTokenType(assignOperator); 2302 _convertAssignOperatorToTokenType(assignOperator);
2259 DartType operandType = stack.removeLast(); 2303 DartType operandType = stack.removeLast();
2260 _pushPropertyBinaryExpression( 2304 _pushPropertyBinaryExpression(
2261 targetType, propertyName, binaryOperator, operandType); 2305 targetType, propertyName, binaryOperator, operandType);
2262 } 2306 }
2263 } 2307 }
2264 2308
2265 void _doAssignToRef() { 2309 void _doAssignToRef() {
2266 refPtr++; 2310 EntityRef ref = _getNextRef();
2311 ReferenceableElementForLink element = unit.resolveRef(ref.reference);
2312 _throwIfInstanceFieldOrAccessor(element);
2267 UnlinkedExprAssignOperator operator = 2313 UnlinkedExprAssignOperator operator =
2268 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; 2314 unlinkedConst.assignmentOperators[assignmentOperatorPtr++];
2269 if (operator == UnlinkedExprAssignOperator.assign) { 2315 if (operator == UnlinkedExprAssignOperator.assign) {
2270 // The type of the assignment is the type of the value, 2316 // The type of the assignment is the type of the value,
2271 // which is already in the stack. 2317 // which is already in the stack.
2272 } else if (isIncrementOrDecrement(operator)) { 2318 } else if (isIncrementOrDecrement(operator)) {
2273 // TODO(scheglov) implement 2319 // TODO(scheglov) implement
2274 stack.add(DynamicTypeImpl.instance); 2320 stack.add(DynamicTypeImpl.instance);
2275 } else { 2321 } else {
2276 stack.removeLast(); 2322 stack.removeLast();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2314 DartType target = stack.removeLast(); 2360 DartType target = stack.removeLast();
2315 if (target.isDynamic) { 2361 if (target.isDynamic) {
2316 target = typeProvider.objectType; 2362 target = typeProvider.objectType;
2317 } 2363 }
2318 String propertyName = _getNextString(); 2364 String propertyName = _getNextString();
2319 stack.add(() { 2365 stack.add(() {
2320 if (target is InterfaceType) { 2366 if (target is InterfaceType) {
2321 ExecutableElement element = target 2367 ExecutableElement element = target
2322 .lookUpInheritedGetterOrMethod(propertyName, library: library); 2368 .lookUpInheritedGetterOrMethod(propertyName, library: library);
2323 if (element != null) { 2369 if (element != null) {
2370 _throwIfInstanceFieldOrAccessor(element);
2324 if (element is PropertyAccessorElement) { 2371 if (element is PropertyAccessorElement) {
2325 return element.returnType; 2372 return element.returnType;
2326 } else { 2373 } else {
2327 // Method tear-off 2374 // Method tear-off
2328 return element.type; 2375 return element.type;
2329 } 2376 }
2330 } 2377 }
2331 } 2378 }
2332 return DynamicTypeImpl.instance; 2379 return DynamicTypeImpl.instance;
2333 }()); 2380 }());
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 } 2476 }
2430 2477
2431 void _doInvokeMethodRef() { 2478 void _doInvokeMethodRef() {
2432 int numNamed = _getNextInt(); 2479 int numNamed = _getNextInt();
2433 int numPositional = _getNextInt(); 2480 int numPositional = _getNextInt();
2434 List<String> namedArgNames = _getNextStrings(numNamed); 2481 List<String> namedArgNames = _getNextStrings(numNamed);
2435 List<DartType> namedArgTypeList = _popList(numNamed); 2482 List<DartType> namedArgTypeList = _popList(numNamed);
2436 List<DartType> positionalArgTypes = _popList(numPositional); 2483 List<DartType> positionalArgTypes = _popList(numPositional);
2437 EntityRef ref = _getNextRef(); 2484 EntityRef ref = _getNextRef();
2438 ReferenceableElementForLink element = unit.resolveRef(ref.reference); 2485 ReferenceableElementForLink element = unit.resolveRef(ref.reference);
2486 _throwIfInstanceFieldOrAccessor(element);
2439 List<DartType> typeArguments = _getTypeArguments(); 2487 List<DartType> typeArguments = _getTypeArguments();
2440 stack.add(() { 2488 stack.add(() {
2441 DartType rawType = element.asStaticType; 2489 DartType rawType = element.asStaticType;
2442 if (rawType is FunctionType) { 2490 if (rawType is FunctionType) {
2443 FunctionType inferredType = _inferExecutableType( 2491 FunctionType inferredType = _inferExecutableType(
2444 rawType, 2492 rawType,
2445 numNamed, 2493 numNamed,
2446 numPositional, 2494 numPositional,
2447 namedArgNames, 2495 namedArgNames,
2448 namedArgTypeList, 2496 namedArgTypeList,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2502 if (ref.paramReference != 0) { 2550 if (ref.paramReference != 0) {
2503 stack.add(typeProvider.typeType); 2551 stack.add(typeProvider.typeType);
2504 } else { 2552 } else {
2505 // Synthetic function types can't be directly referred 2553 // Synthetic function types can't be directly referred
2506 // to by expressions. 2554 // to by expressions.
2507 assert(ref.syntheticReturnType == null); 2555 assert(ref.syntheticReturnType == null);
2508 // Nor can implicit function types derived from 2556 // Nor can implicit function types derived from
2509 // function-typed parameters. 2557 // function-typed parameters.
2510 assert(ref.implicitFunctionTypeIndices.isEmpty); 2558 assert(ref.implicitFunctionTypeIndices.isEmpty);
2511 ReferenceableElementForLink element = unit.resolveRef(ref.reference); 2559 ReferenceableElementForLink element = unit.resolveRef(ref.reference);
2560 _throwIfInstanceFieldOrAccessor(element);
2512 stack.add(element.asStaticType); 2561 stack.add(element.asStaticType);
2513 } 2562 }
2514 } 2563 }
2515 2564
2516 /** 2565 /**
2517 * Find the parameter in scope called [parameterName] and return its type. 2566 * Find the parameter in scope called [parameterName] and return its type.
2518 */ 2567 */
2519 DartType _findParameterType(String parameterName) { 2568 DartType _findParameterType(String parameterName) {
2520 FunctionElementForLink_Local f = this.function; 2569 FunctionElementForLink_Local f = this.function;
2521 while (true) { 2570 while (true) {
(...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after
3926 * The name of the non-static members that is being accessed. 3975 * The name of the non-static members that is being accessed.
3927 */ 3976 */
3928 final String _name; 3977 final String _name;
3929 3978
3930 /** 3979 /**
3931 * The library in which the access occurs. This determines whether private 3980 * The library in which the access occurs. This determines whether private
3932 * names are accessible. 3981 * names are accessible.
3933 */ 3982 */
3934 final LibraryElementForLink _library; 3983 final LibraryElementForLink _library;
3935 3984
3985 bool _elementReady = false;
3986 ExecutableElement _element;
3987
3936 NonstaticMemberElementForLink(this._library, this._target, this._name); 3988 NonstaticMemberElementForLink(this._library, this._target, this._name);
3937 3989
3938 @override 3990 @override
3939 ConstVariableNode get asConstVariable => _target.asConstVariable; 3991 ConstVariableNode get asConstVariable => _target.asConstVariable;
3940 3992
3941 @override 3993 /**
3942 DartType get asStaticType { 3994 * TODO(scheglov) document
3943 if (_library._linker.strongMode) { 3995 */
3996 bool get hasInstanceGetterReference {
3997 ExecutableElement element = asExecutableElement;
3998 if (element is PropertyAccessorElement) {
3999 return !element.isStatic;
4000 }
4001 ReferenceableElementForLink target = _target;
4002 if (target is NonstaticMemberElementForLink) {
4003 return target.hasInstanceGetterReference;
4004 }
4005 return false;
4006 }
4007
4008 /**
4009 * TODO((scheglov) document
4010 */
4011 ExecutableElement get asExecutableElement {
4012 if (!_elementReady) {
4013 _elementReady = true;
3944 DartType targetType = _target.asStaticType; 4014 DartType targetType = _target.asStaticType;
3945 if (targetType.isDynamic) { 4015 if (targetType.isDynamic) {
3946 targetType = _library._linker.typeProvider.objectType; 4016 targetType = _library._linker.typeProvider.objectType;
3947 } 4017 }
3948 if (targetType is InterfaceType) { 4018 if (targetType is InterfaceType) {
3949 ExecutableElement element = 4019 _element =
3950 targetType.lookUpInheritedGetterOrMethod(_name, library: _library); 4020 targetType.lookUpInheritedGetterOrMethod(_name, library: _library);
3951 if (element != null) {
3952 if (element is PropertyAccessorElement) {
3953 return element.returnType;
3954 } else {
3955 // Method tear-off
3956 return element.type;
3957 }
3958 }
3959 } 4021 }
3960 // TODO(paulberry): handle .call on function types and .toString or 4022 // TODO(paulberry): handle .call on function types and .toString or
3961 // .hashCode on all types. 4023 // .hashCode on all types.
3962 } 4024 }
4025 return _element;
4026 }
4027
4028 @override
4029 DartType get asStaticType {
4030 if (_library._linker.strongMode) {
4031 ExecutableElement element = asExecutableElement;
4032 if (element != null) {
4033 if (element is PropertyAccessorElement) {
4034 return element.returnType;
4035 } else {
4036 // Method tear-off
4037 return element.type;
4038 }
4039 }
4040 }
3963 return DynamicTypeImpl.instance; 4041 return DynamicTypeImpl.instance;
3964 } 4042 }
3965 4043
3966 @override 4044 @override
3967 TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode; 4045 TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode;
3968 4046
3969 @override 4047 @override
3970 ReferenceableElementForLink getContainedName(String name) { 4048 ReferenceableElementForLink getContainedName(String name) {
3971 return new NonstaticMemberElementForLink(_library, this, name); 4049 return new NonstaticMemberElementForLink(_library, this, name);
3972 } 4050 }
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
4463 List<TypeParameterElement> get typeParameters { 4541 List<TypeParameterElement> get typeParameters {
4464 // TODO(paulberry): is this correct for fields in generic classes? 4542 // TODO(paulberry): is this correct for fields in generic classes?
4465 return const []; 4543 return const [];
4466 } 4544 }
4467 4545
4468 /** 4546 /**
4469 * Compute the type of the corresponding variable, which may depend on the 4547 * Compute the type of the corresponding variable, which may depend on the
4470 * progress of type inference. 4548 * progress of type inference.
4471 */ 4549 */
4472 DartType computeVariableType() { 4550 DartType computeVariableType() {
4473 if (variable.hasImplicitType && 4551 // if (variable.hasImplicitType &&
4474 !isStatic && 4552 // !isStatic &&
4475 !variable.compilationUnit.isTypeInferenceComplete) { 4553 // !variable.compilationUnit.isTypeInferenceComplete) {
4476 // This is an instance field and we are currently inferring types in the 4554 // // This is an instance field and we are currently inferring types in the
4477 // library cycle containing it. So we shouldn't use the inferred type 4555 // // library cycle containing it. So we shouldn't use the inferred type
4478 // (even if we have already computed it), since that would lead to 4556 // // (even if we have already computed it), since that would lead to
4479 // non-deterministic type inference results. 4557 // // non-deterministic type inference results.
4480 return DynamicTypeImpl.instance; 4558 // return DynamicTypeImpl.instance;
4481 } else { 4559 // } else {
4482 return variable.type; 4560 return variable.type;
4483 } 4561 // }
4484 } 4562 }
4485 4563
4486 @override 4564 @override
4487 ReferenceableElementForLink getContainedName(String name) { 4565 ReferenceableElementForLink getContainedName(String name) {
4488 return new NonstaticMemberElementForLink(library, this, name); 4566 return new NonstaticMemberElementForLink(library, this, name);
4489 } 4567 }
4490 4568
4491 @override 4569 @override
4492 FunctionElementForLink_Local getLocalFunction(int index) { 4570 FunctionElementForLink_Local getLocalFunction(int index) {
4493 if (index == 0) { 4571 if (index == 0) {
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
4732 /** 4810 /**
4733 * Specialization of [Node] used to construct the type inference dependency 4811 * Specialization of [Node] used to construct the type inference dependency
4734 * graph. 4812 * graph.
4735 */ 4813 */
4736 class TypeInferenceNode extends Node<TypeInferenceNode> { 4814 class TypeInferenceNode extends Node<TypeInferenceNode> {
4737 /** 4815 /**
4738 * The [FunctionElementForLink_Local] to which this node refers. 4816 * The [FunctionElementForLink_Local] to which this node refers.
4739 */ 4817 */
4740 final FunctionElementForLink_Local functionElement; 4818 final FunctionElementForLink_Local functionElement;
4741 4819
4820 /**
4821 * TODO(scheglov) document
4822 */
4823 bool _hasError = false;
4824
4742 TypeInferenceNode(this.functionElement); 4825 TypeInferenceNode(this.functionElement);
4743 4826
4744 @override 4827 @override
4745 bool get isEvaluated => functionElement._hasTypeBeenInferred; 4828 bool get isEvaluated => functionElement._hasTypeBeenInferred;
4746 4829
4747 /** 4830 /**
4748 * Collect the type inference dependencies in [unlinkedExecutable] (which 4831 * Collect the type inference dependencies in [unlinkedExecutable] (which
4749 * should be interpreted relative to [compilationUnit]) and store them in 4832 * should be interpreted relative to [compilationUnit]) and store them in
4750 * [dependencies]. 4833 * [dependencies].
4751 */ 4834 */
(...skipping 17 matching lines...) Expand all
4769 int numInts = unlinkedConst.ints[intPtr++]; 4852 int numInts = unlinkedConst.ints[intPtr++];
4770 intPtr += numInts; 4853 intPtr += numInts;
4771 break; 4854 break;
4772 case UnlinkedExprOperation.concatenate: 4855 case UnlinkedExprOperation.concatenate:
4773 intPtr++; 4856 intPtr++;
4774 break; 4857 break;
4775 case UnlinkedExprOperation.pushReference: 4858 case UnlinkedExprOperation.pushReference:
4776 EntityRef ref = unlinkedConst.references[refPtr++]; 4859 EntityRef ref = unlinkedConst.references[refPtr++];
4777 // TODO(paulberry): cache these resolved references for 4860 // TODO(paulberry): cache these resolved references for
4778 // later use by evaluate(). 4861 // later use by evaluate().
4779 TypeInferenceNode dependency = 4862 ReferenceableElementForLink element =
4780 compilationUnit.resolveRef(ref.reference).asTypeInferenceNode; 4863 compilationUnit.resolveRef(ref.reference);
4864 // // Type inference using instance fields is not allowed.
4865 // // So, we need to report an error and fail the inference.
4866 // if (element is VariableElementForLink) {
4867 // var variable = element as VariableElementForLink;
4868 // if (!variable.isStatic) {
4869 // _hasError = true;
4870 // dependencies.clear();
4871 // return;
4872 // }
4873 // }
4874 TypeInferenceNode dependency = element.asTypeInferenceNode;
4781 if (dependency != null) { 4875 if (dependency != null) {
4782 dependencies.add(dependency); 4876 dependencies.add(dependency);
4783 } 4877 }
4784 break; 4878 break;
4785 case UnlinkedExprOperation.invokeConstructor: 4879 case UnlinkedExprOperation.invokeConstructor:
4786 refPtr++; 4880 refPtr++;
4787 intPtr += 2; 4881 intPtr += 2;
4788 break; 4882 break;
4789 case UnlinkedExprOperation.makeUntypedList: 4883 case UnlinkedExprOperation.makeUntypedList:
4790 case UnlinkedExprOperation.makeUntypedMap: 4884 case UnlinkedExprOperation.makeUntypedMap:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4840 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[]; 4934 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
4841 collectDependencies(dependencies, functionElement._unlinkedExecutable, 4935 collectDependencies(dependencies, functionElement._unlinkedExecutable,
4842 functionElement.compilationUnit); 4936 functionElement.compilationUnit);
4843 return dependencies; 4937 return dependencies;
4844 } 4938 }
4845 4939
4846 void evaluate(bool inCycle) { 4940 void evaluate(bool inCycle) {
4847 if (inCycle) { 4941 if (inCycle) {
4848 functionElement._setInferredType(DynamicTypeImpl.instance); 4942 functionElement._setInferredType(DynamicTypeImpl.instance);
4849 } else { 4943 } else {
4850 var bodyType = new ExprTypeComputer(functionElement).compute(); 4944 var computer = new ExprTypeComputer(functionElement);
4851 if (functionElement.isAsynchronous) { 4945 if (computer.hasError) {
4852 var linker = functionElement.compilationUnit.library._linker; 4946 functionElement._setInferredType(DynamicTypeImpl.instance);
4853 var typeProvider = linker.typeProvider; 4947 } else {
4854 var typeSystem = linker.typeSystem; 4948 DartType bodyType = computer.compute();
4855 if (bodyType.isDartAsyncFutureOr) { 4949 if (functionElement.isAsynchronous) {
4856 bodyType = (bodyType as InterfaceType).typeArguments[0]; 4950 var linker = functionElement.compilationUnit.library._linker;
4951 var typeProvider = linker.typeProvider;
4952 var typeSystem = linker.typeSystem;
4953 if (bodyType.isDartAsyncFutureOr) {
4954 bodyType = (bodyType as InterfaceType).typeArguments[0];
4955 }
4956 bodyType = typeProvider.futureType
4957 .instantiate([bodyType.flattenFutures(typeSystem)]);
4857 } 4958 }
4858 bodyType = typeProvider.futureType 4959 functionElement._setInferredType(bodyType);
4859 .instantiate([bodyType.flattenFutures(typeSystem)]);
4860 } 4960 }
4861 functionElement._setInferredType(bodyType);
4862 } 4961 }
4863 } 4962 }
4864 4963
4865 @override 4964 @override
4866 String toString() => 'TypeInferenceNode($functionElement)'; 4965 String toString() => 'TypeInferenceNode($functionElement)';
4867 } 4966 }
4868 4967
4869 class TypeProviderForLink extends TypeProviderBase { 4968 class TypeProviderForLink extends TypeProviderBase {
4870 final Linker _linker; 4969 final Linker _linker;
4871 4970
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
5183 * there are no type parameters in scope. 5282 * there are no type parameters in scope.
5184 */ 5283 */
5185 TypeParameterizedElementMixin get _typeParameterContext; 5284 TypeParameterizedElementMixin get _typeParameterContext;
5186 5285
5187 @override 5286 @override
5188 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 5287 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
5189 5288
5190 @override 5289 @override
5191 String toString() => '$enclosingElement.$name'; 5290 String toString() => '$enclosingElement.$name';
5192 } 5291 }
5292
5293 /**
5294 * TODO(scheglov) document
5295 */
5296 class _InferenceFailedError {
5297 final String message;
5298
5299 _InferenceFailedError(this.message);
5300 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698