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

Side by Side Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 2754423002: Fail inference when an instance field is referenced. (Closed)
Patch Set: Clean up and move tests. 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
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/summary/summarize_const_expr.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 * 139 *
140 * The libraries are prelinked, and a map is returned whose keys are the URIs of 140 * The libraries are prelinked, and a map is returned whose keys are the URIs of
141 * the libraries in this build unit, and whose values are the corresponding 141 * the libraries in this build unit, and whose values are the corresponding
142 * [LinkedLibraryBuilder]s. 142 * [LinkedLibraryBuilder]s.
143 */ 143 */
144 Map<String, LinkedLibraryBuilder> setupForLink(Set<String> libraryUris, 144 Map<String, LinkedLibraryBuilder> setupForLink(Set<String> libraryUris,
145 GetUnitCallback getUnit, GetDeclaredVariable getDeclaredVariable) { 145 GetUnitCallback getUnit, GetDeclaredVariable getDeclaredVariable) {
146 Map<String, LinkedLibraryBuilder> linkedLibraries = 146 Map<String, LinkedLibraryBuilder> linkedLibraries =
147 <String, LinkedLibraryBuilder>{}; 147 <String, LinkedLibraryBuilder>{};
148 for (String absoluteUri in libraryUris) { 148 for (String absoluteUri in libraryUris) {
149 Uri uri = Uri.parse(absoluteUri);
150 linkedLibraries[absoluteUri] = prelink( 149 linkedLibraries[absoluteUri] = prelink(
151 absoluteUri, 150 absoluteUri,
152 getUnit(absoluteUri), 151 getUnit(absoluteUri),
153 getUnit, 152 getUnit,
154 (String absoluteUri) => getUnit(absoluteUri)?.publicNamespace, 153 (String absoluteUri) => getUnit(absoluteUri)?.publicNamespace,
155 getDeclaredVariable); 154 getDeclaredVariable);
156 } 155 }
157 return linkedLibraries; 156 return linkedLibraries;
158 } 157 }
159 158
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 'Linker tried to access linked type from current build unit'); 1281 'Linker tried to access linked type from current build unit');
1283 } 1282 }
1284 1283
1285 /** 1284 /**
1286 * Perform type inference and const cycle detection on this 1285 * Perform type inference and const cycle detection on this
1287 * compilation unit. 1286 * compilation unit.
1288 */ 1287 */
1289 void link() { 1288 void link() {
1290 if (library._linker.strongMode) { 1289 if (library._linker.strongMode) {
1291 new InstanceMemberInferrer(enclosingElement._linker.typeProvider, 1290 new InstanceMemberInferrer(enclosingElement._linker.typeProvider,
1292 enclosingElement.inheritanceManager) 1291 enclosingElement.inheritanceManager, new Set<FieldElement>())
1293 .inferCompilationUnit(this); 1292 .inferCompilationUnit(this);
1294 for (TopLevelVariableElementForLink variable in topLevelVariables) { 1293 for (TopLevelVariableElementForLink variable in topLevelVariables) {
1295 variable.link(this); 1294 variable.link(this);
1296 } 1295 }
1297 } 1296 }
1298 for (ClassElementForLink classElement in types) { 1297 for (ClassElementForLink classElement in types) {
1299 classElement.link(this); 1298 classElement.link(this);
1300 } 1299 }
1301 } 1300 }
1302 1301
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 final Linker linker; 1975 final Linker linker;
1977 final TypeProvider typeProvider; 1976 final TypeProvider typeProvider;
1978 final UnlinkedExpr unlinkedConst; 1977 final UnlinkedExpr unlinkedConst;
1979 1978
1980 final List<DartType> stack = <DartType>[]; 1979 final List<DartType> stack = <DartType>[];
1981 int intPtr = 0; 1980 int intPtr = 0;
1982 int refPtr = 0; 1981 int refPtr = 0;
1983 int strPtr = 0; 1982 int strPtr = 0;
1984 int assignmentOperatorPtr = 0; 1983 int assignmentOperatorPtr = 0;
1985 1984
1985 bool hasError = false;
1986
1986 factory ExprTypeComputer(FunctionElementForLink_Local functionElement) { 1987 factory ExprTypeComputer(FunctionElementForLink_Local functionElement) {
1987 CompilationUnitElementForLink unit = functionElement.compilationUnit; 1988 CompilationUnitElementForLink unit = functionElement.compilationUnit;
1988 LibraryElementForLink library = unit.enclosingElement; 1989 LibraryElementForLink library = unit.enclosingElement;
1989 Linker linker = library._linker; 1990 Linker linker = library._linker;
1990 TypeProvider typeProvider = linker.typeProvider; 1991 TypeProvider typeProvider = linker.typeProvider;
1991 UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr; 1992 UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr;
1992 return new ExprTypeComputer._( 1993 return new ExprTypeComputer._(
1993 functionElement, unit, library, linker, typeProvider, unlinkedConst); 1994 functionElement, unit, library, linker, typeProvider, unlinkedConst);
1994 } 1995 }
1995 1996
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 case UnlinkedExprOperation.pushNull: 2041 case UnlinkedExprOperation.pushNull:
2041 stack.add(typeProvider.nullType); 2042 stack.add(typeProvider.nullType);
2042 break; 2043 break;
2043 case UnlinkedExprOperation.pushSuper: 2044 case UnlinkedExprOperation.pushSuper:
2044 stack.add(DynamicTypeImpl.instance); 2045 stack.add(DynamicTypeImpl.instance);
2045 break; 2046 break;
2046 case UnlinkedExprOperation.pushThis: 2047 case UnlinkedExprOperation.pushThis:
2047 stack.add(DynamicTypeImpl.instance); 2048 stack.add(DynamicTypeImpl.instance);
2048 break; 2049 break;
2049 case UnlinkedExprOperation.pushReference: 2050 case UnlinkedExprOperation.pushReference:
2050 _doPushReference(); 2051 try {
2052 _doPushReference();
2053 } on _InferenceFailedError {
2054 hasError = true;
2055 return DynamicTypeImpl.instance;
2056 }
2051 break; 2057 break;
2052 case UnlinkedExprOperation.extractProperty: 2058 case UnlinkedExprOperation.extractProperty:
2053 _doExtractProperty(); 2059 try {
2060 _doExtractProperty();
2061 } on _InferenceFailedError {
2062 hasError = true;
2063 return DynamicTypeImpl.instance;
2064 }
2054 break; 2065 break;
2055 case UnlinkedExprOperation.invokeConstructor: 2066 case UnlinkedExprOperation.invokeConstructor:
2056 _doInvokeConstructor(); 2067 _doInvokeConstructor();
2057 break; 2068 break;
2058 case UnlinkedExprOperation.makeUntypedList: 2069 case UnlinkedExprOperation.makeUntypedList:
2059 _doMakeUntypedList(); 2070 _doMakeUntypedList();
2060 break; 2071 break;
2061 case UnlinkedExprOperation.makeUntypedMap: 2072 case UnlinkedExprOperation.makeUntypedMap:
2062 _doMakeUntypedMap(); 2073 _doMakeUntypedMap();
2063 break; 2074 break;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2125 break; 2136 break;
2126 case UnlinkedExprOperation.lessEqual: 2137 case UnlinkedExprOperation.lessEqual:
2127 _computeBinaryExpressionType(TokenType.LT_EQ); 2138 _computeBinaryExpressionType(TokenType.LT_EQ);
2128 break; 2139 break;
2129 case UnlinkedExprOperation.modulo: 2140 case UnlinkedExprOperation.modulo:
2130 _computeBinaryExpressionType(TokenType.PERCENT); 2141 _computeBinaryExpressionType(TokenType.PERCENT);
2131 break; 2142 break;
2132 case UnlinkedExprOperation.conditional: 2143 case UnlinkedExprOperation.conditional:
2133 _doConditional(); 2144 _doConditional();
2134 break; 2145 break;
2146 case UnlinkedExprOperation.assignToIndex:
2147 case UnlinkedExprOperation.assignToProperty:
2135 case UnlinkedExprOperation.assignToRef: 2148 case UnlinkedExprOperation.assignToRef:
2136 _doAssignToRef(); 2149 hasError = true;
2137 break; 2150 return DynamicTypeImpl.instance;
2138 case UnlinkedExprOperation.assignToProperty:
2139 _doAssignToProperty();
2140 break;
2141 case UnlinkedExprOperation.assignToIndex:
2142 _doAssignToIndex();
2143 break;
2144 case UnlinkedExprOperation.await: 2151 case UnlinkedExprOperation.await:
2145 _doAwait(); 2152 _doAwait();
2146 break; 2153 break;
2147 case UnlinkedExprOperation.extractIndex: 2154 case UnlinkedExprOperation.extractIndex:
2148 _doExtractIndex(); 2155 _doExtractIndex();
2149 break; 2156 break;
2150 case UnlinkedExprOperation.invokeMethodRef: 2157 case UnlinkedExprOperation.invokeMethodRef:
2151 _doInvokeMethodRef(); 2158 try {
2159 _doInvokeMethodRef();
2160 } on _InferenceFailedError {
2161 hasError = true;
2162 return DynamicTypeImpl.instance;
2163 }
2152 break; 2164 break;
2153 case UnlinkedExprOperation.invokeMethod: 2165 case UnlinkedExprOperation.invokeMethod:
2154 _doInvokeMethod(); 2166 _doInvokeMethod();
2155 break; 2167 break;
2156 case UnlinkedExprOperation.cascadeSectionBegin: 2168 case UnlinkedExprOperation.cascadeSectionBegin:
2157 stack.add(stack.last); 2169 stack.add(stack.last);
2158 break; 2170 break;
2159 case UnlinkedExprOperation.cascadeSectionEnd: 2171 case UnlinkedExprOperation.cascadeSectionEnd:
2160 stack.removeLast(); 2172 stack.removeLast();
2161 break; 2173 break;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2210 operand.lookUpInheritedMethod(operatorName, library: library); 2222 operand.lookUpInheritedMethod(operatorName, library: library);
2211 if (method != null) { 2223 if (method != null) {
2212 DartType type = method.returnType; 2224 DartType type = method.returnType;
2213 stack.add(type); 2225 stack.add(type);
2214 return; 2226 return;
2215 } 2227 }
2216 } 2228 }
2217 stack.add(DynamicTypeImpl.instance); 2229 stack.add(DynamicTypeImpl.instance);
2218 } 2230 }
2219 2231
2220 void _doAssignToIndex() {
2221 stack.removeLast();
2222 stack.removeLast();
2223 UnlinkedExprAssignOperator operator =
2224 unlinkedConst.assignmentOperators[assignmentOperatorPtr++];
2225 if (operator == UnlinkedExprAssignOperator.assign) {
2226 // The type of the assignment is the type of the value,
2227 // which is already in the stack.
2228 } else if (isIncrementOrDecrement(operator)) {
2229 // TODO(scheglov) implement
2230 stack.add(DynamicTypeImpl.instance);
2231 } else {
2232 stack.removeLast();
2233 // TODO(scheglov) implement
2234 stack.add(DynamicTypeImpl.instance);
2235 }
2236 }
2237
2238 void _doAssignToProperty() {
2239 DartType targetType = stack.removeLast();
2240 String propertyName = _getNextString();
2241 UnlinkedExprAssignOperator assignOperator =
2242 unlinkedConst.assignmentOperators[assignmentOperatorPtr++];
2243 if (assignOperator == UnlinkedExprAssignOperator.assign) {
2244 // The type of the assignment is the type of the value,
2245 // which is already in the stack.
2246 } else if (assignOperator == UnlinkedExprAssignOperator.postfixDecrement ||
2247 assignOperator == UnlinkedExprAssignOperator.postfixIncrement) {
2248 DartType propertyType = _getPropertyType(targetType, propertyName);
2249 stack.add(propertyType);
2250 } else if (assignOperator == UnlinkedExprAssignOperator.prefixDecrement) {
2251 _pushPropertyBinaryExpression(
2252 targetType, propertyName, TokenType.MINUS, typeProvider.intType);
2253 } else if (assignOperator == UnlinkedExprAssignOperator.prefixIncrement) {
2254 _pushPropertyBinaryExpression(
2255 targetType, propertyName, TokenType.PLUS, typeProvider.intType);
2256 } else {
2257 TokenType binaryOperator =
2258 _convertAssignOperatorToTokenType(assignOperator);
2259 DartType operandType = stack.removeLast();
2260 _pushPropertyBinaryExpression(
2261 targetType, propertyName, binaryOperator, operandType);
2262 }
2263 }
2264
2265 void _doAssignToRef() {
2266 refPtr++;
2267 UnlinkedExprAssignOperator operator =
2268 unlinkedConst.assignmentOperators[assignmentOperatorPtr++];
2269 if (operator == UnlinkedExprAssignOperator.assign) {
2270 // The type of the assignment is the type of the value,
2271 // which is already in the stack.
2272 } else if (isIncrementOrDecrement(operator)) {
2273 // TODO(scheglov) implement
2274 stack.add(DynamicTypeImpl.instance);
2275 } else {
2276 stack.removeLast();
2277 // TODO(scheglov) implement
2278 stack.add(DynamicTypeImpl.instance);
2279 }
2280 }
2281
2282 void _doAwait() { 2232 void _doAwait() {
2283 DartType type = stack.removeLast(); 2233 DartType type = stack.removeLast();
2284 DartType typeArgument = type?.flattenFutures(linker.typeSystem); 2234 DartType typeArgument = type?.flattenFutures(linker.typeSystem);
2285 typeArgument = _dynamicIfNull(typeArgument); 2235 typeArgument = _dynamicIfNull(typeArgument);
2286 stack.add(typeArgument); 2236 stack.add(typeArgument);
2287 } 2237 }
2288 2238
2289 void _doConditional() { 2239 void _doConditional() {
2290 DartType elseType = stack.removeLast(); 2240 DartType elseType = stack.removeLast();
2291 DartType thenType = stack.removeLast(); 2241 DartType thenType = stack.removeLast();
(...skipping 22 matching lines...) Expand all
2314 DartType target = stack.removeLast(); 2264 DartType target = stack.removeLast();
2315 if (target.isDynamic) { 2265 if (target.isDynamic) {
2316 target = typeProvider.objectType; 2266 target = typeProvider.objectType;
2317 } 2267 }
2318 String propertyName = _getNextString(); 2268 String propertyName = _getNextString();
2319 stack.add(() { 2269 stack.add(() {
2320 if (target is InterfaceType) { 2270 if (target is InterfaceType) {
2321 ExecutableElement element = target 2271 ExecutableElement element = target
2322 .lookUpInheritedGetterOrMethod(propertyName, library: library); 2272 .lookUpInheritedGetterOrMethod(propertyName, library: library);
2323 if (element != null) { 2273 if (element != null) {
2274 _throwIfInstanceFieldOrAccessor(element);
2324 if (element is PropertyAccessorElement) { 2275 if (element is PropertyAccessorElement) {
2325 return element.returnType; 2276 return element.returnType;
2326 } else { 2277 } else {
2327 // Method tear-off 2278 // Method tear-off
2328 return element.type; 2279 return element.type;
2329 } 2280 }
2330 } 2281 }
2331 } 2282 }
2332 return DynamicTypeImpl.instance; 2283 return DynamicTypeImpl.instance;
2333 }()); 2284 }());
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 } 2380 }
2430 2381
2431 void _doInvokeMethodRef() { 2382 void _doInvokeMethodRef() {
2432 int numNamed = _getNextInt(); 2383 int numNamed = _getNextInt();
2433 int numPositional = _getNextInt(); 2384 int numPositional = _getNextInt();
2434 List<String> namedArgNames = _getNextStrings(numNamed); 2385 List<String> namedArgNames = _getNextStrings(numNamed);
2435 List<DartType> namedArgTypeList = _popList(numNamed); 2386 List<DartType> namedArgTypeList = _popList(numNamed);
2436 List<DartType> positionalArgTypes = _popList(numPositional); 2387 List<DartType> positionalArgTypes = _popList(numPositional);
2437 EntityRef ref = _getNextRef(); 2388 EntityRef ref = _getNextRef();
2438 ReferenceableElementForLink element = unit.resolveRef(ref.reference); 2389 ReferenceableElementForLink element = unit.resolveRef(ref.reference);
2390 _throwIfInstanceFieldOrAccessor(element);
2439 List<DartType> typeArguments = _getTypeArguments(); 2391 List<DartType> typeArguments = _getTypeArguments();
2440 stack.add(() { 2392 stack.add(() {
2441 DartType rawType = element.asStaticType; 2393 DartType rawType = element.asStaticType;
2442 if (rawType is FunctionType) { 2394 if (rawType is FunctionType) {
2443 FunctionType inferredType = _inferExecutableType( 2395 FunctionType inferredType = _inferExecutableType(
2444 rawType, 2396 rawType,
2445 numNamed, 2397 numNamed,
2446 numPositional, 2398 numPositional,
2447 namedArgNames, 2399 namedArgNames,
2448 namedArgTypeList, 2400 namedArgTypeList,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2502 if (ref.paramReference != 0) { 2454 if (ref.paramReference != 0) {
2503 stack.add(typeProvider.typeType); 2455 stack.add(typeProvider.typeType);
2504 } else { 2456 } else {
2505 // Synthetic function types can't be directly referred 2457 // Synthetic function types can't be directly referred
2506 // to by expressions. 2458 // to by expressions.
2507 assert(ref.syntheticReturnType == null); 2459 assert(ref.syntheticReturnType == null);
2508 // Nor can implicit function types derived from 2460 // Nor can implicit function types derived from
2509 // function-typed parameters. 2461 // function-typed parameters.
2510 assert(ref.implicitFunctionTypeIndices.isEmpty); 2462 assert(ref.implicitFunctionTypeIndices.isEmpty);
2511 ReferenceableElementForLink element = unit.resolveRef(ref.reference); 2463 ReferenceableElementForLink element = unit.resolveRef(ref.reference);
2464 _throwIfInstanceFieldOrAccessor(element);
2512 stack.add(element.asStaticType); 2465 stack.add(element.asStaticType);
2513 } 2466 }
2514 } 2467 }
2515 2468
2516 /** 2469 /**
2517 * Find the parameter in scope called [parameterName] and return its type. 2470 * Find the parameter in scope called [parameterName] and return its type.
2518 */ 2471 */
2519 DartType _findParameterType(String parameterName) { 2472 DartType _findParameterType(String parameterName) {
2520 FunctionElementForLink_Local f = this.function; 2473 FunctionElementForLink_Local f = this.function;
2521 while (true) { 2474 while (true) {
(...skipping 30 matching lines...) Expand all
2552 result[i] = _getNextString(); 2505 result[i] = _getNextString();
2553 } 2506 }
2554 return result; 2507 return result;
2555 } 2508 }
2556 2509
2557 DartType _getNextTypeRef() { 2510 DartType _getNextTypeRef() {
2558 EntityRef ref = _getNextRef(); 2511 EntityRef ref = _getNextRef();
2559 return unit.resolveTypeRef(ref, function.typeParameterContext); 2512 return unit.resolveTypeRef(ref, function.typeParameterContext);
2560 } 2513 }
2561 2514
2562 /**
2563 * Return the type of the property with the given [propertyName] in the
2564 * given [targetType]. May return `dynamic` if the property cannot be
2565 * resolved.
2566 */
2567 DartType _getPropertyType(DartType targetType, String propertyName) {
2568 return targetType is InterfaceType
2569 ? targetType
2570 .lookUpInheritedGetter(propertyName, library: library)
2571 ?.returnType
2572 : DynamicTypeImpl.instance;
2573 }
2574
2575 List<DartType> _getTypeArguments() { 2515 List<DartType> _getTypeArguments() {
2576 int numTypeArguments = _getNextInt(); 2516 int numTypeArguments = _getNextInt();
2577 List<DartType> typeArguments = new List<DartType>(numTypeArguments); 2517 List<DartType> typeArguments = new List<DartType>(numTypeArguments);
2578 for (int i = 0; i < numTypeArguments; i++) { 2518 for (int i = 0; i < numTypeArguments; i++) {
2579 typeArguments[i] = _getNextTypeRef(); 2519 typeArguments[i] = _getNextTypeRef();
2580 } 2520 }
2581 return typeArguments; 2521 return typeArguments;
2582 } 2522 }
2583 2523
2584 FunctionType _inferExecutableType( 2524 FunctionType _inferExecutableType(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2655 DartType type = method.returnType; 2595 DartType type = method.returnType;
2656 type = linker.typeSystem 2596 type = linker.typeSystem
2657 .refineBinaryExpressionType(left, operator, right, type); 2597 .refineBinaryExpressionType(left, operator, right, type);
2658 stack.add(type); 2598 stack.add(type);
2659 return; 2599 return;
2660 } 2600 }
2661 } 2601 }
2662 stack.add(DynamicTypeImpl.instance); 2602 stack.add(DynamicTypeImpl.instance);
2663 } 2603 }
2664 2604
2665 /** 2605 void _throwIfInstanceFieldOrAccessor(Object element) {
2666 * Extract the property with the given [propertyName], apply the operator 2606 if (element is NonstaticMemberElementForLink &&
2667 * with the given [operandType], push the type of applying operand of the 2607 element.hasInstanceGetterReference ||
2668 * given [operandType]. 2608 element is FieldElement && !element.isStatic ||
2669 */ 2609 element is PropertyAccessorElement && !element.isStatic) {
2670 void _pushPropertyBinaryExpression(DartType targetType, String propertyName, 2610 throw new _InferenceFailedError(
2671 TokenType operator, DartType operandType) { 2611 'Instance fields cannot be used for type inference.');
2672 DartType propertyType = _getPropertyType(targetType, propertyName);
2673 _pushBinaryOperatorType(propertyType, operator, operandType);
2674 }
2675
2676 static TokenType _convertAssignOperatorToTokenType(
2677 UnlinkedExprAssignOperator o) {
2678 switch (o) {
2679 case UnlinkedExprAssignOperator.assign:
2680 return null;
2681 case UnlinkedExprAssignOperator.ifNull:
2682 return TokenType.QUESTION_QUESTION;
2683 case UnlinkedExprAssignOperator.multiply:
2684 return TokenType.STAR;
2685 case UnlinkedExprAssignOperator.divide:
2686 return TokenType.SLASH;
2687 case UnlinkedExprAssignOperator.floorDivide:
2688 return TokenType.TILDE_SLASH;
2689 case UnlinkedExprAssignOperator.modulo:
2690 return TokenType.PERCENT;
2691 case UnlinkedExprAssignOperator.plus:
2692 return TokenType.PLUS;
2693 case UnlinkedExprAssignOperator.minus:
2694 return TokenType.MINUS;
2695 case UnlinkedExprAssignOperator.shiftLeft:
2696 return TokenType.LT_LT;
2697 case UnlinkedExprAssignOperator.shiftRight:
2698 return TokenType.GT_GT;
2699 case UnlinkedExprAssignOperator.bitAnd:
2700 return TokenType.AMPERSAND;
2701 case UnlinkedExprAssignOperator.bitXor:
2702 return TokenType.CARET;
2703 case UnlinkedExprAssignOperator.bitOr:
2704 return TokenType.BAR;
2705 case UnlinkedExprAssignOperator.prefixIncrement:
2706 return TokenType.PLUS_PLUS;
2707 case UnlinkedExprAssignOperator.prefixDecrement:
2708 return TokenType.MINUS_MINUS;
2709 case UnlinkedExprAssignOperator.postfixIncrement:
2710 return TokenType.PLUS_PLUS;
2711 case UnlinkedExprAssignOperator.postfixDecrement:
2712 return TokenType.MINUS_MINUS;
2713 } 2612 }
2714 return null;
2715 } 2613 }
2716 } 2614 }
2717 2615
2718 /** 2616 /**
2719 * Element representing a field resynthesized from a summary during 2617 * Element representing a field resynthesized from a summary during
2720 * linking. 2618 * linking.
2721 */ 2619 */
2722 abstract class FieldElementForLink implements FieldElement { 2620 abstract class FieldElementForLink implements FieldElement {
2723 @override 2621 @override
2724 PropertyAccessorElementForLink get getter; 2622 PropertyAccessorElementForLink get getter;
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after
3926 * The name of the non-static members that is being accessed. 3824 * The name of the non-static members that is being accessed.
3927 */ 3825 */
3928 final String _name; 3826 final String _name;
3929 3827
3930 /** 3828 /**
3931 * The library in which the access occurs. This determines whether private 3829 * The library in which the access occurs. This determines whether private
3932 * names are accessible. 3830 * names are accessible.
3933 */ 3831 */
3934 final LibraryElementForLink _library; 3832 final LibraryElementForLink _library;
3935 3833
3834 /**
3835 * Whether the [_element] was computed (even if to `null`).
3836 */
3837 bool _elementReady = false;
3838
3839 /**
3840 * The cached [ExecutableElement] represented by this element.
3841 */
3842 ExecutableElement _element;
3843
3936 NonstaticMemberElementForLink(this._library, this._target, this._name); 3844 NonstaticMemberElementForLink(this._library, this._target, this._name);
3937 3845
3938 @override 3846 @override
3939 ConstVariableNode get asConstVariable => _target.asConstVariable; 3847 ConstVariableNode get asConstVariable => _target.asConstVariable;
3940 3848
3941 @override 3849 /**
3942 DartType get asStaticType { 3850 * Return the [ExecutableElement] represented by this element.
3943 if (_library._linker.strongMode) { 3851 */
3852 ExecutableElement get asExecutableElement {
3853 if (!_elementReady) {
3854 _elementReady = true;
3944 DartType targetType = _target.asStaticType; 3855 DartType targetType = _target.asStaticType;
3945 if (targetType.isDynamic) { 3856 if (targetType.isDynamic) {
3946 targetType = _library._linker.typeProvider.objectType; 3857 targetType = _library._linker.typeProvider.objectType;
3947 } 3858 }
3948 if (targetType is InterfaceType) { 3859 if (targetType is InterfaceType) {
3949 ExecutableElement element = 3860 _element =
3950 targetType.lookUpInheritedGetterOrMethod(_name, library: _library); 3861 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 } 3862 }
3960 // TODO(paulberry): handle .call on function types and .toString or 3863 // TODO(paulberry): handle .call on function types and .toString or
3961 // .hashCode on all types. 3864 // .hashCode on all types.
3962 } 3865 }
3866 return _element;
3867 }
3868
3869 @override
3870 DartType get asStaticType {
3871 if (_library._linker.strongMode) {
3872 ExecutableElement element = asExecutableElement;
3873 if (element != null) {
3874 if (element is PropertyAccessorElement) {
3875 return element.returnType;
3876 } else {
3877 // Method tear-off
3878 return element.type;
3879 }
3880 }
3881 }
3963 return DynamicTypeImpl.instance; 3882 return DynamicTypeImpl.instance;
3964 } 3883 }
3965 3884
3966 @override 3885 @override
3967 TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode; 3886 TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode;
3968 3887
3888 /**
3889 * Return `true` if this element is an instance getter, or its target
3890 * is an instance getter (recursively).
3891 */
3892 bool get hasInstanceGetterReference {
3893 ExecutableElement element = asExecutableElement;
3894 if (element is PropertyAccessorElement) {
3895 return !element.isStatic;
3896 }
3897 ReferenceableElementForLink target = _target;
3898 if (target is NonstaticMemberElementForLink) {
3899 return target.hasInstanceGetterReference;
3900 }
3901 return false;
3902 }
3903
3969 @override 3904 @override
3970 ReferenceableElementForLink getContainedName(String name) { 3905 ReferenceableElementForLink getContainedName(String name) {
3971 return new NonstaticMemberElementForLink(_library, this, name); 3906 return new NonstaticMemberElementForLink(_library, this, name);
3972 } 3907 }
3973 3908
3974 @override 3909 @override
3975 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 3910 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
3976 3911
3977 @override 3912 @override
3978 String toString() => '$_target.(dynamic)$_name'; 3913 String toString() => '$_target.(dynamic)$_name';
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
4173 @override 4108 @override
4174 bool get isSynthetic => true; 4109 bool get isSynthetic => true;
4175 4110
4176 @override 4111 @override
4177 String get name => 'x'; 4112 String get name => 'x';
4178 4113
4179 @override 4114 @override
4180 ParameterKind get parameterKind => ParameterKind.REQUIRED; 4115 ParameterKind get parameterKind => ParameterKind.REQUIRED;
4181 4116
4182 @override 4117 @override
4183 DartType get type => enclosingElement.computeVariableType(); 4118 DartType get type => enclosingElement.variable.type;
4184 4119
4185 @override 4120 @override
4186 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 4121 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
4187 } 4122 }
4188 4123
4189 /** 4124 /**
4190 * Mixin used by elements that can have parameters. 4125 * Mixin used by elements that can have parameters.
4191 */ 4126 */
4192 abstract class ParameterParentElementForLink implements Element { 4127 abstract class ParameterParentElementForLink implements Element {
4193 List<ParameterElement> _parameters; 4128 List<ParameterElement> _parameters;
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
4445 } 4380 }
4446 } 4381 }
4447 return _parameters; 4382 return _parameters;
4448 } 4383 }
4449 4384
4450 @override 4385 @override
4451 DartType get returnType { 4386 DartType get returnType {
4452 if (isSetter) { 4387 if (isSetter) {
4453 return VoidTypeImpl.instance; 4388 return VoidTypeImpl.instance;
4454 } else { 4389 } else {
4455 return computeVariableType(); 4390 return variable.type;
4456 } 4391 }
4457 } 4392 }
4458 4393
4459 @override 4394 @override
4460 FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this); 4395 FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
4461 4396
4462 @override 4397 @override
4463 List<TypeParameterElement> get typeParameters { 4398 List<TypeParameterElement> get typeParameters {
4464 // TODO(paulberry): is this correct for fields in generic classes? 4399 // TODO(paulberry): is this correct for fields in generic classes?
4465 return const []; 4400 return const [];
4466 } 4401 }
4467 4402
4468 /**
4469 * Compute the type of the corresponding variable, which may depend on the
4470 * progress of type inference.
4471 */
4472 DartType computeVariableType() {
4473 if (variable.hasImplicitType &&
4474 !isStatic &&
4475 !variable.compilationUnit.isTypeInferenceComplete) {
4476 // 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
4478 // (even if we have already computed it), since that would lead to
4479 // non-deterministic type inference results.
4480 return DynamicTypeImpl.instance;
4481 } else {
4482 return variable.type;
4483 }
4484 }
4485
4486 @override 4403 @override
4487 ReferenceableElementForLink getContainedName(String name) { 4404 ReferenceableElementForLink getContainedName(String name) {
4488 return new NonstaticMemberElementForLink(library, this, name); 4405 return new NonstaticMemberElementForLink(library, this, name);
4489 } 4406 }
4490 4407
4491 @override 4408 @override
4492 FunctionElementForLink_Local getLocalFunction(int index) { 4409 FunctionElementForLink_Local getLocalFunction(int index) {
4493 if (index == 0) { 4410 if (index == 0) {
4494 return variable.initializer; 4411 return variable.initializer;
4495 } else { 4412 } else {
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
4840 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[]; 4757 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
4841 collectDependencies(dependencies, functionElement._unlinkedExecutable, 4758 collectDependencies(dependencies, functionElement._unlinkedExecutable,
4842 functionElement.compilationUnit); 4759 functionElement.compilationUnit);
4843 return dependencies; 4760 return dependencies;
4844 } 4761 }
4845 4762
4846 void evaluate(bool inCycle) { 4763 void evaluate(bool inCycle) {
4847 if (inCycle) { 4764 if (inCycle) {
4848 functionElement._setInferredType(DynamicTypeImpl.instance); 4765 functionElement._setInferredType(DynamicTypeImpl.instance);
4849 } else { 4766 } else {
4850 var bodyType = new ExprTypeComputer(functionElement).compute(); 4767 var computer = new ExprTypeComputer(functionElement);
4851 if (functionElement.isAsynchronous) { 4768 DartType bodyType = computer.compute();
4852 var linker = functionElement.compilationUnit.library._linker; 4769 if (computer.hasError) {
4853 var typeProvider = linker.typeProvider; 4770 functionElement._setInferredType(DynamicTypeImpl.instance);
4854 var typeSystem = linker.typeSystem; 4771 } else {
4855 if (bodyType.isDartAsyncFutureOr) { 4772 if (functionElement.isAsynchronous) {
4856 bodyType = (bodyType as InterfaceType).typeArguments[0]; 4773 var linker = functionElement.compilationUnit.library._linker;
4774 var typeProvider = linker.typeProvider;
4775 var typeSystem = linker.typeSystem;
4776 if (bodyType.isDartAsyncFutureOr) {
4777 bodyType = (bodyType as InterfaceType).typeArguments[0];
4778 }
4779 bodyType = typeProvider.futureType
4780 .instantiate([bodyType.flattenFutures(typeSystem)]);
4857 } 4781 }
4858 bodyType = typeProvider.futureType 4782 functionElement._setInferredType(bodyType);
4859 .instantiate([bodyType.flattenFutures(typeSystem)]);
4860 } 4783 }
4861 functionElement._setInferredType(bodyType);
4862 } 4784 }
4863 } 4785 }
4864 4786
4865 @override 4787 @override
4866 String toString() => 'TypeInferenceNode($functionElement)'; 4788 String toString() => 'TypeInferenceNode($functionElement)';
4867 } 4789 }
4868 4790
4869 class TypeProviderForLink extends TypeProviderBase { 4791 class TypeProviderForLink extends TypeProviderBase {
4870 final Linker _linker; 4792 final Linker _linker;
4871 4793
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
5183 * there are no type parameters in scope. 5105 * there are no type parameters in scope.
5184 */ 5106 */
5185 TypeParameterizedElementMixin get _typeParameterContext; 5107 TypeParameterizedElementMixin get _typeParameterContext;
5186 5108
5187 @override 5109 @override
5188 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 5110 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
5189 5111
5190 @override 5112 @override
5191 String toString() => '$enclosingElement.$name'; 5113 String toString() => '$enclosingElement.$name';
5192 } 5114 }
5115
5116 /**
5117 * This exception is thrown when [ExprTypeComputer] cannot inference the type.
5118 */
5119 class _InferenceFailedError {
5120 final String message;
5121
5122 _InferenceFailedError(this.message);
5123 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/summary/summarize_const_expr.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698