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

Side by Side Diff: pkg/analyzer/lib/src/task/strong/checker.dart

Issue 1893053002: Handle fuzzy optional parameters correctly. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
6 // refactored to fit into analyzer. 6 // refactored to fit into analyzer.
7 library analyzer.src.task.strong.checker; 7 library analyzer.src.task.strong.checker;
8 8
9 import 'package:analyzer/analyzer.dart'; 9 import 'package:analyzer/analyzer.dart';
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 // Malformed type - fallback on analyzer error. 793 // Malformed type - fallback on analyzer error.
794 return null; 794 return null;
795 } 795 }
796 } 796 }
797 797
798 DartType _getStaticType(Expression expr) { 798 DartType _getStaticType(Expression expr) {
799 DartType t = expr.staticType ?? DynamicTypeImpl.instance; 799 DartType t = expr.staticType ?? DynamicTypeImpl.instance;
800 800
801 // Remove fuzzy arrow if possible. 801 // Remove fuzzy arrow if possible.
802 if (t is FunctionType && StaticInfo.isKnownFunction(expr)) { 802 if (t is FunctionType && StaticInfo.isKnownFunction(expr)) {
803 t = _removeFuzz(t); 803 t = rules.functionTypeToConcreteType(typeProvider, t);
804 } 804 }
805 805
806 return t; 806 return t;
807 } 807 }
808 808
809 /// Given an expression, return its type assuming it is 809 /// Given an expression, return its type assuming it is
810 /// in the caller position of a call (that is, accounting 810 /// in the caller position of a call (that is, accounting
811 /// for the possibility of a call method). Returns null 811 /// for the possibility of a call method). Returns null
812 /// if expression is not statically callable. 812 /// if expression is not statically callable.
813 FunctionType _getTypeAsCaller(Expression node) { 813 FunctionType _getTypeAsCaller(Expression node) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 if (info is CoercionInfo) { 901 if (info is CoercionInfo) {
902 // TODO(jmesserly): if we're run again on the same AST, we'll produce the 902 // TODO(jmesserly): if we're run again on the same AST, we'll produce the
903 // same annotations. This should be harmless. This might go away once 903 // same annotations. This should be harmless. This might go away once
904 // CodeChecker is integrated better with analyzer, as it will know that 904 // CodeChecker is integrated better with analyzer, as it will know that
905 // checking has already been performed. 905 // checking has already been performed.
906 // assert(CoercionInfo.get(info.node) == null); 906 // assert(CoercionInfo.get(info.node) == null);
907 CoercionInfo.set(info.node, info); 907 CoercionInfo.set(info.node, info);
908 } 908 }
909 } 909 }
910 910
911 /// Remove "fuzzy arrow" in this function type.
912 ///
913 /// Normally we treat dynamically typed parameters as bottom for function
914 /// types. This allows type tests such as `if (f is SingleArgFunction)`.
915 /// It also requires a dynamic check on the parameter type to call these
916 /// functions.
917 ///
918 /// When we convert to a strict arrow, dynamically typed parameters become
919 /// top. This is safe to do for known functions, like top-level or local
920 /// functions and static methods. Those functions must already be essentially
921 /// treating dynamic as top.
922 ///
923 /// Only the outer-most arrow can be strict. Any others must be fuzzy, because
924 /// we don't know what function value will be passed there.
925 // TODO(jmesserly): should we use a real "fuzzyArrow" bit on the function
926 // type? That would allow us to implement this in the subtype relation.
927 // TODO(jmesserly): we'll need to factor this differently if we want to
928 // move CodeChecker's functionality into existing analyzer. Likely we can
929 // let the Expression have a strict arrow, then in places were we do
930 // inference, convert back to a fuzzy arrow.
931 FunctionType _removeFuzz(FunctionType t) {
932 bool foundFuzz = false;
933 List<ParameterElement> parameters = <ParameterElement>[];
934 for (ParameterElement p in t.parameters) {
935 ParameterElement newP = _removeParameterFuzz(p);
936 parameters.add(newP);
937 if (p != newP) foundFuzz = true;
938 }
939 if (!foundFuzz) {
940 return t;
941 }
942
943 FunctionElementImpl function = new FunctionElementImpl("", -1);
944 function.synthetic = true;
945 function.returnType = t.returnType;
946 function.shareTypeParameters(t.typeFormals);
947 function.shareParameters(parameters);
948 return function.type = new FunctionTypeImpl(function);
949 }
950
951 /// Removes fuzzy arrow, see [_removeFuzz].
952 ParameterElement _removeParameterFuzz(ParameterElement p) {
953 if (p.type.isDynamic) {
954 return new ParameterElementImpl.synthetic(
955 p.name, typeProvider.objectType, p.parameterKind);
956 }
957 return p;
958 }
959
960 DartType _specializedBinaryReturnType( 911 DartType _specializedBinaryReturnType(
961 TokenType op, DartType t1, DartType t2, DartType normalReturnType) { 912 TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
962 // This special cases binary return types as per 16.26 and 16.27 of the 913 // This special cases binary return types as per 16.26 and 16.27 of the
963 // Dart language spec. 914 // Dart language spec.
964 switch (op) { 915 switch (op) {
965 case TokenType.PLUS: 916 case TokenType.PLUS:
966 case TokenType.MINUS: 917 case TokenType.MINUS:
967 case TokenType.STAR: 918 case TokenType.STAR:
968 case TokenType.TILDE_SLASH: 919 case TokenType.TILDE_SLASH:
969 case TokenType.PERCENT: 920 case TokenType.PERCENT:
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 } while (!current.isObject && !visited.contains(current)); 1253 } while (!current.isObject && !visited.contains(current));
1303 } 1254 }
1304 1255
1305 void _recordMessage(StaticInfo info) { 1256 void _recordMessage(StaticInfo info) {
1306 if (info == null) return; 1257 if (info == null) return;
1307 var error = info.toAnalysisError(); 1258 var error = info.toAnalysisError();
1308 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; 1259 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true;
1309 _reporter.onError(error); 1260 _reporter.onError(error);
1310 } 1261 }
1311 } 1262 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/type_system.dart ('k') | pkg/analyzer/test/src/task/strong/checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698