| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 1859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1870 if (isAmpAmp || isBarBar) { | 1870 if (isAmpAmp || isBarBar) { |
| 1871 Expression lhsCondition = node.leftOperand; | 1871 Expression lhsCondition = node.leftOperand; |
| 1872 if (!_isDebugConstant(lhsCondition)) { | 1872 if (!_isDebugConstant(lhsCondition)) { |
| 1873 EvaluationResultImpl lhsResult = _getConstantBooleanValue(lhsCondition); | 1873 EvaluationResultImpl lhsResult = _getConstantBooleanValue(lhsCondition); |
| 1874 if (lhsResult != null) { | 1874 if (lhsResult != null) { |
| 1875 if (lhsResult.value.toBoolValue() == true && isBarBar) { | 1875 if (lhsResult.value.toBoolValue() == true && isBarBar) { |
| 1876 // report error on else block: true || !e! | 1876 // report error on else block: true || !e! |
| 1877 _errorReporter.reportErrorForNode( | 1877 _errorReporter.reportErrorForNode( |
| 1878 HintCode.DEAD_CODE, node.rightOperand); | 1878 HintCode.DEAD_CODE, node.rightOperand); |
| 1879 // only visit the LHS: | 1879 // only visit the LHS: |
| 1880 _safelyVisit(lhsCondition); | 1880 lhsCondition?.accept(this); |
| 1881 return null; | 1881 return null; |
| 1882 } else if (lhsResult.value.toBoolValue() == false && isAmpAmp) { | 1882 } else if (lhsResult.value.toBoolValue() == false && isAmpAmp) { |
| 1883 // report error on if block: false && !e! | 1883 // report error on if block: false && !e! |
| 1884 _errorReporter.reportErrorForNode( | 1884 _errorReporter.reportErrorForNode( |
| 1885 HintCode.DEAD_CODE, node.rightOperand); | 1885 HintCode.DEAD_CODE, node.rightOperand); |
| 1886 // only visit the LHS: | 1886 // only visit the LHS: |
| 1887 _safelyVisit(lhsCondition); | 1887 lhsCondition?.accept(this); |
| 1888 return null; | 1888 return null; |
| 1889 } | 1889 } |
| 1890 } | 1890 } |
| 1891 } | 1891 } |
| 1892 // How do we want to handle the RHS? It isn't dead code, but "pointless" | 1892 // How do we want to handle the RHS? It isn't dead code, but "pointless" |
| 1893 // or "obscure"... | 1893 // or "obscure"... |
| 1894 // Expression rhsCondition = node.getRightOperand(); | 1894 // Expression rhsCondition = node.getRightOperand(); |
| 1895 // ValidResult rhsResult = getConstantBooleanValue(rhsCondition); | 1895 // ValidResult rhsResult = getConstantBooleanValue(rhsCondition); |
| 1896 // if (rhsResult != null) { | 1896 // if (rhsResult != null) { |
| 1897 // if (rhsResult == ValidResult.RESULT_TRUE && isBarBar) { | 1897 // if (rhsResult == ValidResult.RESULT_TRUE && isBarBar) { |
| 1898 // // report error on else block: !e! || true | 1898 // // report error on else block: !e! || true |
| 1899 // errorReporter.reportError(HintCode.DEAD_CODE, node.getRightOpe
rand()); | 1899 // errorReporter.reportError(HintCode.DEAD_CODE, node.getRightOpe
rand()); |
| 1900 // // only visit the RHS: | 1900 // // only visit the RHS: |
| 1901 // safelyVisit(rhsCondition); | 1901 // rhsCondition?.accept(this); |
| 1902 // return null; | 1902 // return null; |
| 1903 // } else if (rhsResult == ValidResult.RESULT_FALSE && isAmpAmp) { | 1903 // } else if (rhsResult == ValidResult.RESULT_FALSE && isAmpAmp) { |
| 1904 // // report error on if block: !e! && false | 1904 // // report error on if block: !e! && false |
| 1905 // errorReporter.reportError(HintCode.DEAD_CODE, node.getRightOpe
rand()); | 1905 // errorReporter.reportError(HintCode.DEAD_CODE, node.getRightOpe
rand()); |
| 1906 // // only visit the RHS: | 1906 // // only visit the RHS: |
| 1907 // safelyVisit(rhsCondition); | 1907 // rhsCondition?.accept(this); |
| 1908 // return null; | 1908 // return null; |
| 1909 // } | 1909 // } |
| 1910 // } | 1910 // } |
| 1911 } | 1911 } |
| 1912 return super.visitBinaryExpression(node); | 1912 return super.visitBinaryExpression(node); |
| 1913 } | 1913 } |
| 1914 | 1914 |
| 1915 /** | 1915 /** |
| 1916 * For each [Block], this method reports and error on all statements between t
he end of the | 1916 * For each [Block], this method reports and error on all statements between t
he end of the |
| 1917 * block and the first return statement (assuming there it is not at the end o
f the block.) | 1917 * block and the first return statement (assuming there it is not at the end o
f the block.) |
| 1918 * | 1918 * |
| 1919 * @param node the block to evaluate | 1919 * @param node the block to evaluate |
| 1920 */ | 1920 */ |
| 1921 @override | 1921 @override |
| 1922 Object visitBlock(Block node) { | 1922 Object visitBlock(Block node) { |
| 1923 NodeList<Statement> statements = node.statements; | 1923 NodeList<Statement> statements = node.statements; |
| 1924 _checkForDeadStatementsInNodeList(statements); | 1924 _checkForDeadStatementsInNodeList(statements); |
| 1925 return null; | 1925 return null; |
| 1926 } | 1926 } |
| 1927 | 1927 |
| 1928 @override | 1928 @override |
| 1929 Object visitConditionalExpression(ConditionalExpression node) { | 1929 Object visitConditionalExpression(ConditionalExpression node) { |
| 1930 Expression conditionExpression = node.condition; | 1930 Expression conditionExpression = node.condition; |
| 1931 _safelyVisit(conditionExpression); | 1931 conditionExpression?.accept(this); |
| 1932 if (!_isDebugConstant(conditionExpression)) { | 1932 if (!_isDebugConstant(conditionExpression)) { |
| 1933 EvaluationResultImpl result = | 1933 EvaluationResultImpl result = |
| 1934 _getConstantBooleanValue(conditionExpression); | 1934 _getConstantBooleanValue(conditionExpression); |
| 1935 if (result != null) { | 1935 if (result != null) { |
| 1936 if (result.value.toBoolValue() == true) { | 1936 if (result.value.toBoolValue() == true) { |
| 1937 // report error on else block: true ? 1 : !2! | 1937 // report error on else block: true ? 1 : !2! |
| 1938 _errorReporter.reportErrorForNode( | 1938 _errorReporter.reportErrorForNode( |
| 1939 HintCode.DEAD_CODE, node.elseExpression); | 1939 HintCode.DEAD_CODE, node.elseExpression); |
| 1940 _safelyVisit(node.thenExpression); | 1940 node.thenExpression?.accept(this); |
| 1941 return null; | 1941 return null; |
| 1942 } else { | 1942 } else { |
| 1943 // report error on if block: false ? !1! : 2 | 1943 // report error on if block: false ? !1! : 2 |
| 1944 _errorReporter.reportErrorForNode( | 1944 _errorReporter.reportErrorForNode( |
| 1945 HintCode.DEAD_CODE, node.thenExpression); | 1945 HintCode.DEAD_CODE, node.thenExpression); |
| 1946 _safelyVisit(node.elseExpression); | 1946 node.elseExpression?.accept(this); |
| 1947 return null; | 1947 return null; |
| 1948 } | 1948 } |
| 1949 } | 1949 } |
| 1950 } | 1950 } |
| 1951 return super.visitConditionalExpression(node); | 1951 return super.visitConditionalExpression(node); |
| 1952 } | 1952 } |
| 1953 | 1953 |
| 1954 @override | 1954 @override |
| 1955 Object visitIfStatement(IfStatement node) { | 1955 Object visitIfStatement(IfStatement node) { |
| 1956 Expression conditionExpression = node.condition; | 1956 Expression conditionExpression = node.condition; |
| 1957 _safelyVisit(conditionExpression); | 1957 conditionExpression?.accept(this); |
| 1958 if (!_isDebugConstant(conditionExpression)) { | 1958 if (!_isDebugConstant(conditionExpression)) { |
| 1959 EvaluationResultImpl result = | 1959 EvaluationResultImpl result = |
| 1960 _getConstantBooleanValue(conditionExpression); | 1960 _getConstantBooleanValue(conditionExpression); |
| 1961 if (result != null) { | 1961 if (result != null) { |
| 1962 if (result.value.toBoolValue() == true) { | 1962 if (result.value.toBoolValue() == true) { |
| 1963 // report error on else block: if(true) {} else {!} | 1963 // report error on else block: if(true) {} else {!} |
| 1964 Statement elseStatement = node.elseStatement; | 1964 Statement elseStatement = node.elseStatement; |
| 1965 if (elseStatement != null) { | 1965 if (elseStatement != null) { |
| 1966 _errorReporter.reportErrorForNode( | 1966 _errorReporter.reportErrorForNode( |
| 1967 HintCode.DEAD_CODE, elseStatement); | 1967 HintCode.DEAD_CODE, elseStatement); |
| 1968 _safelyVisit(node.thenStatement); | 1968 node.thenStatement?.accept(this); |
| 1969 return null; | 1969 return null; |
| 1970 } | 1970 } |
| 1971 } else { | 1971 } else { |
| 1972 // report error on if block: if (false) {!} else {} | 1972 // report error on if block: if (false) {!} else {} |
| 1973 _errorReporter.reportErrorForNode( | 1973 _errorReporter.reportErrorForNode( |
| 1974 HintCode.DEAD_CODE, node.thenStatement); | 1974 HintCode.DEAD_CODE, node.thenStatement); |
| 1975 _safelyVisit(node.elseStatement); | 1975 node.elseStatement?.accept(this); |
| 1976 return null; | 1976 return null; |
| 1977 } | 1977 } |
| 1978 } | 1978 } |
| 1979 } | 1979 } |
| 1980 return super.visitIfStatement(node); | 1980 return super.visitIfStatement(node); |
| 1981 } | 1981 } |
| 1982 | 1982 |
| 1983 @override | 1983 @override |
| 1984 Object visitSwitchCase(SwitchCase node) { | 1984 Object visitSwitchCase(SwitchCase node) { |
| 1985 _checkForDeadStatementsInNodeList(node.statements); | 1985 _checkForDeadStatementsInNodeList(node.statements); |
| 1986 return super.visitSwitchCase(node); | 1986 return super.visitSwitchCase(node); |
| 1987 } | 1987 } |
| 1988 | 1988 |
| 1989 @override | 1989 @override |
| 1990 Object visitSwitchDefault(SwitchDefault node) { | 1990 Object visitSwitchDefault(SwitchDefault node) { |
| 1991 _checkForDeadStatementsInNodeList(node.statements); | 1991 _checkForDeadStatementsInNodeList(node.statements); |
| 1992 return super.visitSwitchDefault(node); | 1992 return super.visitSwitchDefault(node); |
| 1993 } | 1993 } |
| 1994 | 1994 |
| 1995 @override | 1995 @override |
| 1996 Object visitTryStatement(TryStatement node) { | 1996 Object visitTryStatement(TryStatement node) { |
| 1997 _safelyVisit(node.body); | 1997 node.body?.accept(this); |
| 1998 _safelyVisit(node.finallyBlock); | 1998 node.finallyBlock?.accept(this); |
| 1999 NodeList<CatchClause> catchClauses = node.catchClauses; | 1999 NodeList<CatchClause> catchClauses = node.catchClauses; |
| 2000 int numOfCatchClauses = catchClauses.length; | 2000 int numOfCatchClauses = catchClauses.length; |
| 2001 List<DartType> visitedTypes = new List<DartType>(); | 2001 List<DartType> visitedTypes = new List<DartType>(); |
| 2002 for (int i = 0; i < numOfCatchClauses; i++) { | 2002 for (int i = 0; i < numOfCatchClauses; i++) { |
| 2003 CatchClause catchClause = catchClauses[i]; | 2003 CatchClause catchClause = catchClauses[i]; |
| 2004 if (catchClause.onKeyword != null) { | 2004 if (catchClause.onKeyword != null) { |
| 2005 // on-catch clause found, verify that the exception type is not a | 2005 // on-catch clause found, verify that the exception type is not a |
| 2006 // subtype of a previous on-catch exception type | 2006 // subtype of a previous on-catch exception type |
| 2007 TypeName typeName = catchClause.exceptionType; | 2007 TypeName typeName = catchClause.exceptionType; |
| 2008 if (typeName != null && typeName.type != null) { | 2008 if (typeName != null && typeName.type != null) { |
| 2009 DartType currentType = typeName.type; | 2009 DartType currentType = typeName.type; |
| 2010 if (currentType.isObject) { | 2010 if (currentType.isObject) { |
| 2011 // Found catch clause clause that has Object as an exception type, | 2011 // Found catch clause clause that has Object as an exception type, |
| 2012 // this is equivalent to having a catch clause that doesn't have an | 2012 // this is equivalent to having a catch clause that doesn't have an |
| 2013 // exception type, visit the block, but generate an error on any | 2013 // exception type, visit the block, but generate an error on any |
| 2014 // following catch clauses (and don't visit them). | 2014 // following catch clauses (and don't visit them). |
| 2015 _safelyVisit(catchClause); | 2015 catchClause?.accept(this); |
| 2016 if (i + 1 != numOfCatchClauses) { | 2016 if (i + 1 != numOfCatchClauses) { |
| 2017 // this catch clause is not the last in the try statement | 2017 // this catch clause is not the last in the try statement |
| 2018 CatchClause nextCatchClause = catchClauses[i + 1]; | 2018 CatchClause nextCatchClause = catchClauses[i + 1]; |
| 2019 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2019 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2020 int offset = nextCatchClause.offset; | 2020 int offset = nextCatchClause.offset; |
| 2021 int length = lastCatchClause.end - offset; | 2021 int length = lastCatchClause.end - offset; |
| 2022 _errorReporter.reportErrorForOffset( | 2022 _errorReporter.reportErrorForOffset( |
| 2023 HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length); | 2023 HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length); |
| 2024 return null; | 2024 return null; |
| 2025 } | 2025 } |
| 2026 } | 2026 } |
| 2027 for (DartType type in visitedTypes) { | 2027 for (DartType type in visitedTypes) { |
| 2028 if (_typeSystem.isSubtypeOf(currentType, type)) { | 2028 if (_typeSystem.isSubtypeOf(currentType, type)) { |
| 2029 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2029 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2030 int offset = catchClause.offset; | 2030 int offset = catchClause.offset; |
| 2031 int length = lastCatchClause.end - offset; | 2031 int length = lastCatchClause.end - offset; |
| 2032 _errorReporter.reportErrorForOffset( | 2032 _errorReporter.reportErrorForOffset( |
| 2033 HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, | 2033 HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, |
| 2034 offset, | 2034 offset, |
| 2035 length, | 2035 length, |
| 2036 [currentType.displayName, type.displayName]); | 2036 [currentType.displayName, type.displayName]); |
| 2037 return null; | 2037 return null; |
| 2038 } | 2038 } |
| 2039 } | 2039 } |
| 2040 visitedTypes.add(currentType); | 2040 visitedTypes.add(currentType); |
| 2041 } | 2041 } |
| 2042 _safelyVisit(catchClause); | 2042 catchClause?.accept(this); |
| 2043 } else { | 2043 } else { |
| 2044 // Found catch clause clause that doesn't have an exception type, | 2044 // Found catch clause clause that doesn't have an exception type, |
| 2045 // visit the block, but generate an error on any following catch clauses | 2045 // visit the block, but generate an error on any following catch clauses |
| 2046 // (and don't visit them). | 2046 // (and don't visit them). |
| 2047 _safelyVisit(catchClause); | 2047 catchClause?.accept(this); |
| 2048 if (i + 1 != numOfCatchClauses) { | 2048 if (i + 1 != numOfCatchClauses) { |
| 2049 // this catch clause is not the last in the try statement | 2049 // this catch clause is not the last in the try statement |
| 2050 CatchClause nextCatchClause = catchClauses[i + 1]; | 2050 CatchClause nextCatchClause = catchClauses[i + 1]; |
| 2051 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2051 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2052 int offset = nextCatchClause.offset; | 2052 int offset = nextCatchClause.offset; |
| 2053 int length = lastCatchClause.end - offset; | 2053 int length = lastCatchClause.end - offset; |
| 2054 _errorReporter.reportErrorForOffset( | 2054 _errorReporter.reportErrorForOffset( |
| 2055 HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length); | 2055 HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length); |
| 2056 return null; | 2056 return null; |
| 2057 } | 2057 } |
| 2058 } | 2058 } |
| 2059 } | 2059 } |
| 2060 return null; | 2060 return null; |
| 2061 } | 2061 } |
| 2062 | 2062 |
| 2063 @override | 2063 @override |
| 2064 Object visitWhileStatement(WhileStatement node) { | 2064 Object visitWhileStatement(WhileStatement node) { |
| 2065 Expression conditionExpression = node.condition; | 2065 Expression conditionExpression = node.condition; |
| 2066 _safelyVisit(conditionExpression); | 2066 conditionExpression?.accept(this); |
| 2067 if (!_isDebugConstant(conditionExpression)) { | 2067 if (!_isDebugConstant(conditionExpression)) { |
| 2068 EvaluationResultImpl result = | 2068 EvaluationResultImpl result = |
| 2069 _getConstantBooleanValue(conditionExpression); | 2069 _getConstantBooleanValue(conditionExpression); |
| 2070 if (result != null) { | 2070 if (result != null) { |
| 2071 if (result.value.toBoolValue() == false) { | 2071 if (result.value.toBoolValue() == false) { |
| 2072 // report error on if block: while (false) {!} | 2072 // report error on if block: while (false) {!} |
| 2073 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.body); | 2073 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.body); |
| 2074 return null; | 2074 return null; |
| 2075 } | 2075 } |
| 2076 } | 2076 } |
| 2077 } | 2077 } |
| 2078 _safelyVisit(node.body); | 2078 node.body?.accept(this); |
| 2079 return null; | 2079 return null; |
| 2080 } | 2080 } |
| 2081 | 2081 |
| 2082 /** | 2082 /** |
| 2083 * Given some [NodeList] of [Statement]s, from either a [Block] or | 2083 * Given some [NodeList] of [Statement]s, from either a [Block] or |
| 2084 * [SwitchMember], this loops through the list in reverse order searching for
statements | 2084 * [SwitchMember], this loops through the list in reverse order searching for
statements |
| 2085 * after a return, unlabeled break or unlabeled continue statement to mark the
m as dead code. | 2085 * after a return, unlabeled break or unlabeled continue statement to mark the
m as dead code. |
| 2086 * | 2086 * |
| 2087 * @param statements some ordered list of statements in a [Block] or [SwitchMe
mber] | 2087 * @param statements some ordered list of statements in a [Block] or [SwitchMe
mber] |
| 2088 */ | 2088 */ |
| 2089 void _checkForDeadStatementsInNodeList(NodeList<Statement> statements) { | 2089 void _checkForDeadStatementsInNodeList(NodeList<Statement> statements) { |
| 2090 int size = statements.length; | 2090 int size = statements.length; |
| 2091 for (int i = 0; i < size; i++) { | 2091 for (int i = 0; i < size; i++) { |
| 2092 Statement currentStatement = statements[i]; | 2092 Statement currentStatement = statements[i]; |
| 2093 _safelyVisit(currentStatement); | 2093 currentStatement?.accept(this); |
| 2094 bool returnOrBreakingStatement = currentStatement is ReturnStatement || | 2094 bool returnOrBreakingStatement = currentStatement is ReturnStatement || |
| 2095 (currentStatement is BreakStatement && | 2095 (currentStatement is BreakStatement && |
| 2096 currentStatement.label == null) || | 2096 currentStatement.label == null) || |
| 2097 (currentStatement is ContinueStatement && | 2097 (currentStatement is ContinueStatement && |
| 2098 currentStatement.label == null); | 2098 currentStatement.label == null); |
| 2099 if (returnOrBreakingStatement && i != size - 1) { | 2099 if (returnOrBreakingStatement && i != size - 1) { |
| 2100 Statement nextStatement = statements[i + 1]; | 2100 Statement nextStatement = statements[i + 1]; |
| 2101 Statement lastStatement = statements[size - 1]; | 2101 Statement lastStatement = statements[size - 1]; |
| 2102 int offset = nextStatement.offset; | 2102 int offset = nextStatement.offset; |
| 2103 int length = lastStatement.end - offset; | 2103 int length = lastStatement.end - offset; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2155 } else if (expression is PropertyAccess) { | 2155 } else if (expression is PropertyAccess) { |
| 2156 PropertyAccess propertyAccess = expression; | 2156 PropertyAccess propertyAccess = expression; |
| 2157 element = propertyAccess.propertyName.staticElement; | 2157 element = propertyAccess.propertyName.staticElement; |
| 2158 } | 2158 } |
| 2159 if (element is PropertyAccessorElement) { | 2159 if (element is PropertyAccessorElement) { |
| 2160 PropertyInducingElement variable = element.variable; | 2160 PropertyInducingElement variable = element.variable; |
| 2161 return variable != null && variable.isConst; | 2161 return variable != null && variable.isConst; |
| 2162 } | 2162 } |
| 2163 return false; | 2163 return false; |
| 2164 } | 2164 } |
| 2165 | |
| 2166 /** | |
| 2167 * If the given node is not `null`, visit this instance of the dead code verif
ier. | |
| 2168 * | |
| 2169 * @param node the node to be visited | |
| 2170 */ | |
| 2171 void _safelyVisit(AstNode node) { | |
| 2172 if (node != null) { | |
| 2173 node.accept(this); | |
| 2174 } | |
| 2175 } | |
| 2176 } | 2165 } |
| 2177 | 2166 |
| 2178 /** | 2167 /** |
| 2179 * A visitor that resolves declarations in an AST structure to already built | 2168 * A visitor that resolves declarations in an AST structure to already built |
| 2180 * elements. | 2169 * elements. |
| 2181 * | 2170 * |
| 2182 * The resulting AST must have everything resolved that would have been resolved | 2171 * The resulting AST must have everything resolved that would have been resolved |
| 2183 * by a [CompilationUnitBuilder] (that is, must be a valid [RESOLVED_UNIT1]). | 2172 * by a [CompilationUnitBuilder] (that is, must be a valid [RESOLVED_UNIT1]). |
| 2184 * This class must not assume that the [CompilationUnitElement] passed to it is | 2173 * This class must not assume that the [CompilationUnitElement] passed to it is |
| 2185 * any more complete than a [COMPILATION_UNIT_ELEMENT]. | 2174 * any more complete than a [COMPILATION_UNIT_ELEMENT]. |
| (...skipping 5489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7675 } | 7664 } |
| 7676 } | 7665 } |
| 7677 | 7666 |
| 7678 @override | 7667 @override |
| 7679 Object visitAnnotation(Annotation node) { | 7668 Object visitAnnotation(Annotation node) { |
| 7680 AstNode parent = node.parent; | 7669 AstNode parent = node.parent; |
| 7681 if (identical(parent, _enclosingClassDeclaration) || | 7670 if (identical(parent, _enclosingClassDeclaration) || |
| 7682 identical(parent, _enclosingFunctionTypeAlias)) { | 7671 identical(parent, _enclosingFunctionTypeAlias)) { |
| 7683 return null; | 7672 return null; |
| 7684 } | 7673 } |
| 7685 safelyVisit(node.name); | 7674 node.name?.accept(this); |
| 7686 safelyVisit(node.constructorName); | 7675 node.constructorName?.accept(this); |
| 7687 Element element = node.element; | 7676 Element element = node.element; |
| 7688 if (element is ExecutableElement) { | 7677 if (element is ExecutableElement) { |
| 7689 InferenceContext.setType(node.arguments, element.type); | 7678 InferenceContext.setType(node.arguments, element.type); |
| 7690 } | 7679 } |
| 7691 safelyVisit(node.arguments); | 7680 node.arguments?.accept(this); |
| 7692 node.accept(elementResolver); | 7681 node.accept(elementResolver); |
| 7693 node.accept(typeAnalyzer); | 7682 node.accept(typeAnalyzer); |
| 7694 ElementAnnotationImpl elementAnnotationImpl = node.elementAnnotation; | 7683 ElementAnnotationImpl elementAnnotationImpl = node.elementAnnotation; |
| 7695 if (elementAnnotationImpl == null) { | 7684 if (elementAnnotationImpl == null) { |
| 7696 // Analyzer ignores annotations on "part of" directives. | 7685 // Analyzer ignores annotations on "part of" directives. |
| 7697 assert(parent is PartOfDirective); | 7686 assert(parent is PartOfDirective); |
| 7698 } else { | 7687 } else { |
| 7699 elementAnnotationImpl.annotationAst = | 7688 elementAnnotationImpl.annotationAst = |
| 7700 new ConstantAstCloner().cloneNode(node); | 7689 new ConstantAstCloner().cloneNode(node); |
| 7701 } | 7690 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7759 | 7748 |
| 7760 @override | 7749 @override |
| 7761 Object visitAssertStatement(AssertStatement node) { | 7750 Object visitAssertStatement(AssertStatement node) { |
| 7762 super.visitAssertStatement(node); | 7751 super.visitAssertStatement(node); |
| 7763 _propagateTrueState(node.condition); | 7752 _propagateTrueState(node.condition); |
| 7764 return null; | 7753 return null; |
| 7765 } | 7754 } |
| 7766 | 7755 |
| 7767 @override | 7756 @override |
| 7768 Object visitAssignmentExpression(AssignmentExpression node) { | 7757 Object visitAssignmentExpression(AssignmentExpression node) { |
| 7769 safelyVisit(node.leftHandSide); | 7758 node.leftHandSide?.accept(this); |
| 7770 TokenType operator = node.operator.type; | 7759 TokenType operator = node.operator.type; |
| 7771 if (operator == TokenType.EQ || | 7760 if (operator == TokenType.EQ || |
| 7772 operator == TokenType.QUESTION_QUESTION_EQ) { | 7761 operator == TokenType.QUESTION_QUESTION_EQ) { |
| 7773 InferenceContext.setType( | 7762 InferenceContext.setType( |
| 7774 node.rightHandSide, node.leftHandSide.staticType); | 7763 node.rightHandSide, node.leftHandSide.staticType); |
| 7775 } | 7764 } |
| 7776 safelyVisit(node.rightHandSide); | 7765 node.rightHandSide?.accept(this); |
| 7777 node.accept(elementResolver); | 7766 node.accept(elementResolver); |
| 7778 node.accept(typeAnalyzer); | 7767 node.accept(typeAnalyzer); |
| 7779 return null; | 7768 return null; |
| 7780 } | 7769 } |
| 7781 | 7770 |
| 7782 @override | 7771 @override |
| 7783 Object visitAwaitExpression(AwaitExpression node) { | 7772 Object visitAwaitExpression(AwaitExpression node) { |
| 7784 // TODO(leafp): Handle the implicit union type here | 7773 // TODO(leafp): Handle the implicit union type here |
| 7785 // https://github.com/dart-lang/sdk/issues/25322 | 7774 // https://github.com/dart-lang/sdk/issues/25322 |
| 7786 DartType contextType = InferenceContext.getType(node); | 7775 DartType contextType = InferenceContext.getType(node); |
| 7787 if (contextType != null) { | 7776 if (contextType != null) { |
| 7788 InterfaceType futureT = typeProvider.futureType | 7777 InterfaceType futureT = typeProvider.futureType |
| 7789 .instantiate([contextType.flattenFutures(typeSystem)]); | 7778 .instantiate([contextType.flattenFutures(typeSystem)]); |
| 7790 InferenceContext.setType(node.expression, futureT); | 7779 InferenceContext.setType(node.expression, futureT); |
| 7791 } | 7780 } |
| 7792 return super.visitAwaitExpression(node); | 7781 return super.visitAwaitExpression(node); |
| 7793 } | 7782 } |
| 7794 | 7783 |
| 7795 @override | 7784 @override |
| 7796 Object visitBinaryExpression(BinaryExpression node) { | 7785 Object visitBinaryExpression(BinaryExpression node) { |
| 7797 TokenType operatorType = node.operator.type; | 7786 TokenType operatorType = node.operator.type; |
| 7798 Expression leftOperand = node.leftOperand; | 7787 Expression leftOperand = node.leftOperand; |
| 7799 Expression rightOperand = node.rightOperand; | 7788 Expression rightOperand = node.rightOperand; |
| 7800 if (operatorType == TokenType.AMPERSAND_AMPERSAND) { | 7789 if (operatorType == TokenType.AMPERSAND_AMPERSAND) { |
| 7801 safelyVisit(leftOperand); | 7790 leftOperand?.accept(this); |
| 7802 if (rightOperand != null) { | 7791 if (rightOperand != null) { |
| 7803 _overrideManager.enterScope(); | 7792 _overrideManager.enterScope(); |
| 7804 try { | 7793 try { |
| 7805 _promoteManager.enterScope(); | 7794 _promoteManager.enterScope(); |
| 7806 try { | 7795 try { |
| 7807 _propagateTrueState(leftOperand); | 7796 _propagateTrueState(leftOperand); |
| 7808 // Type promotion. | 7797 // Type promotion. |
| 7809 _promoteTypes(leftOperand); | 7798 _promoteTypes(leftOperand); |
| 7810 _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand); | 7799 _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand); |
| 7811 _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand); | 7800 _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand); |
| 7812 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( | 7801 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( |
| 7813 rightOperand); | 7802 rightOperand); |
| 7814 // Visit right operand. | 7803 // Visit right operand. |
| 7815 rightOperand.accept(this); | 7804 rightOperand.accept(this); |
| 7816 } finally { | 7805 } finally { |
| 7817 _promoteManager.exitScope(); | 7806 _promoteManager.exitScope(); |
| 7818 } | 7807 } |
| 7819 } finally { | 7808 } finally { |
| 7820 _overrideManager.exitScope(); | 7809 _overrideManager.exitScope(); |
| 7821 } | 7810 } |
| 7822 } | 7811 } |
| 7823 } else if (operatorType == TokenType.BAR_BAR) { | 7812 } else if (operatorType == TokenType.BAR_BAR) { |
| 7824 safelyVisit(leftOperand); | 7813 leftOperand?.accept(this); |
| 7825 if (rightOperand != null) { | 7814 if (rightOperand != null) { |
| 7826 _overrideManager.enterScope(); | 7815 _overrideManager.enterScope(); |
| 7827 try { | 7816 try { |
| 7828 _propagateFalseState(leftOperand); | 7817 _propagateFalseState(leftOperand); |
| 7829 rightOperand.accept(this); | 7818 rightOperand.accept(this); |
| 7830 } finally { | 7819 } finally { |
| 7831 _overrideManager.exitScope(); | 7820 _overrideManager.exitScope(); |
| 7832 } | 7821 } |
| 7833 } | 7822 } |
| 7834 } else { | 7823 } else { |
| 7835 // TODO(leafp): Do downwards inference using the declared type | 7824 // TODO(leafp): Do downwards inference using the declared type |
| 7836 // of the binary operator for other cases. | 7825 // of the binary operator for other cases. |
| 7837 if (operatorType == TokenType.QUESTION_QUESTION) { | 7826 if (operatorType == TokenType.QUESTION_QUESTION) { |
| 7838 InferenceContext.setTypeFromNode(leftOperand, node); | 7827 InferenceContext.setTypeFromNode(leftOperand, node); |
| 7839 InferenceContext.setTypeFromNode(rightOperand, node); | 7828 InferenceContext.setTypeFromNode(rightOperand, node); |
| 7840 } | 7829 } |
| 7841 safelyVisit(leftOperand); | 7830 leftOperand?.accept(this); |
| 7842 safelyVisit(rightOperand); | 7831 rightOperand?.accept(this); |
| 7843 } | 7832 } |
| 7844 node.accept(elementResolver); | 7833 node.accept(elementResolver); |
| 7845 node.accept(typeAnalyzer); | 7834 node.accept(typeAnalyzer); |
| 7846 return null; | 7835 return null; |
| 7847 } | 7836 } |
| 7848 | 7837 |
| 7849 @override | 7838 @override |
| 7850 Object visitBlockFunctionBody(BlockFunctionBody node) { | 7839 Object visitBlockFunctionBody(BlockFunctionBody node) { |
| 7851 _overrideManager.enterScope(); | 7840 _overrideManager.enterScope(); |
| 7852 try { | 7841 try { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7986 _overrideManager.exitScope(); | 7975 _overrideManager.exitScope(); |
| 7987 } | 7976 } |
| 7988 node.accept(elementResolver); | 7977 node.accept(elementResolver); |
| 7989 node.accept(typeAnalyzer); | 7978 node.accept(typeAnalyzer); |
| 7990 return null; | 7979 return null; |
| 7991 } | 7980 } |
| 7992 | 7981 |
| 7993 @override | 7982 @override |
| 7994 Object visitConditionalExpression(ConditionalExpression node) { | 7983 Object visitConditionalExpression(ConditionalExpression node) { |
| 7995 Expression condition = node.condition; | 7984 Expression condition = node.condition; |
| 7996 safelyVisit(condition); | 7985 condition?.accept(this); |
| 7997 Expression thenExpression = node.thenExpression; | 7986 Expression thenExpression = node.thenExpression; |
| 7998 if (thenExpression != null) { | 7987 if (thenExpression != null) { |
| 7999 _overrideManager.enterScope(); | 7988 _overrideManager.enterScope(); |
| 8000 try { | 7989 try { |
| 8001 _promoteManager.enterScope(); | 7990 _promoteManager.enterScope(); |
| 8002 try { | 7991 try { |
| 8003 _propagateTrueState(condition); | 7992 _propagateTrueState(condition); |
| 8004 // Type promotion. | 7993 // Type promotion. |
| 8005 _promoteTypes(condition); | 7994 _promoteTypes(condition); |
| 8006 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); | 7995 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8068 } | 8057 } |
| 8069 | 8058 |
| 8070 @override | 8059 @override |
| 8071 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 8060 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 8072 // | 8061 // |
| 8073 // We visit the expression, but do not visit the field name because it needs | 8062 // We visit the expression, but do not visit the field name because it needs |
| 8074 // to be visited in the context of the constructor field initializer node. | 8063 // to be visited in the context of the constructor field initializer node. |
| 8075 // | 8064 // |
| 8076 FieldElement fieldElement = enclosingClass.getField(node.fieldName.name); | 8065 FieldElement fieldElement = enclosingClass.getField(node.fieldName.name); |
| 8077 InferenceContext.setType(node.expression, fieldElement?.type); | 8066 InferenceContext.setType(node.expression, fieldElement?.type); |
| 8078 safelyVisit(node.expression); | 8067 node.expression?.accept(this); |
| 8079 node.accept(elementResolver); | 8068 node.accept(elementResolver); |
| 8080 node.accept(typeAnalyzer); | 8069 node.accept(typeAnalyzer); |
| 8081 return null; | 8070 return null; |
| 8082 } | 8071 } |
| 8083 | 8072 |
| 8084 @override | 8073 @override |
| 8085 Object visitConstructorName(ConstructorName node) { | 8074 Object visitConstructorName(ConstructorName node) { |
| 8086 // | 8075 // |
| 8087 // We do not visit either the type name, because it won't be visited anyway, | 8076 // We do not visit either the type name, because it won't be visited anyway, |
| 8088 // or the name, because it needs to be visited in the context of the | 8077 // or the name, because it needs to be visited in the context of the |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8219 Expression iterable = node.iterable; | 8208 Expression iterable = node.iterable; |
| 8220 DeclaredIdentifier loopVariable = node.loopVariable; | 8209 DeclaredIdentifier loopVariable = node.loopVariable; |
| 8221 SimpleIdentifier identifier = node.identifier; | 8210 SimpleIdentifier identifier = node.identifier; |
| 8222 if (loopVariable?.type?.type != null) { | 8211 if (loopVariable?.type?.type != null) { |
| 8223 InterfaceType targetType = (node.awaitKeyword == null) | 8212 InterfaceType targetType = (node.awaitKeyword == null) |
| 8224 ? typeProvider.iterableType | 8213 ? typeProvider.iterableType |
| 8225 : typeProvider.streamType; | 8214 : typeProvider.streamType; |
| 8226 InferenceContext.setType( | 8215 InferenceContext.setType( |
| 8227 iterable, targetType.instantiate([loopVariable.type.type])); | 8216 iterable, targetType.instantiate([loopVariable.type.type])); |
| 8228 } | 8217 } |
| 8229 safelyVisit(iterable); | 8218 iterable?.accept(this); |
| 8230 safelyVisit(loopVariable); | 8219 loopVariable?.accept(this); |
| 8231 safelyVisit(identifier); | 8220 identifier?.accept(this); |
| 8232 Statement body = node.body; | 8221 Statement body = node.body; |
| 8233 if (body != null) { | 8222 if (body != null) { |
| 8234 _overrideManager.enterScope(); | 8223 _overrideManager.enterScope(); |
| 8235 try { | 8224 try { |
| 8236 if (loopVariable != null && iterable != null) { | 8225 if (loopVariable != null && iterable != null) { |
| 8237 LocalVariableElement loopElement = loopVariable.element; | 8226 LocalVariableElement loopElement = loopVariable.element; |
| 8238 if (loopElement != null) { | 8227 if (loopElement != null) { |
| 8239 DartType propagatedType = null; | 8228 DartType propagatedType = null; |
| 8240 if (node.awaitKeyword == null) { | 8229 if (node.awaitKeyword == null) { |
| 8241 propagatedType = _getIteratorElementType(iterable); | 8230 propagatedType = _getIteratorElementType(iterable); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 8271 try { | 8260 try { |
| 8272 super.visitForStatement(node); | 8261 super.visitForStatement(node); |
| 8273 } finally { | 8262 } finally { |
| 8274 _overrideManager.exitScope(); | 8263 _overrideManager.exitScope(); |
| 8275 } | 8264 } |
| 8276 return null; | 8265 return null; |
| 8277 } | 8266 } |
| 8278 | 8267 |
| 8279 @override | 8268 @override |
| 8280 void visitForStatementInScope(ForStatement node) { | 8269 void visitForStatementInScope(ForStatement node) { |
| 8281 safelyVisit(node.variables); | 8270 node.variables?.accept(this); |
| 8282 safelyVisit(node.initialization); | 8271 node.initialization?.accept(this); |
| 8283 safelyVisit(node.condition); | 8272 node.condition?.accept(this); |
| 8284 _overrideManager.enterScope(); | 8273 _overrideManager.enterScope(); |
| 8285 try { | 8274 try { |
| 8286 _propagateTrueState(node.condition); | 8275 _propagateTrueState(node.condition); |
| 8287 visitStatementInScope(node.body); | 8276 visitStatementInScope(node.body); |
| 8288 node.updaters.accept(this); | 8277 node.updaters.accept(this); |
| 8289 } finally { | 8278 } finally { |
| 8290 _overrideManager.exitScope(); | 8279 _overrideManager.exitScope(); |
| 8291 } | 8280 } |
| 8292 // TODO(brianwilkerson) If the loop can only be exited because the condition | 8281 // TODO(brianwilkerson) If the loop can only be exited because the condition |
| 8293 // is false, then propagateFalseState(condition); | 8282 // is false, then propagateFalseState(condition); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8343 } | 8332 } |
| 8344 } finally { | 8333 } finally { |
| 8345 _currentFunctionBody = outerFunctionBody; | 8334 _currentFunctionBody = outerFunctionBody; |
| 8346 _enclosingFunction = outerFunction; | 8335 _enclosingFunction = outerFunction; |
| 8347 } | 8336 } |
| 8348 return null; | 8337 return null; |
| 8349 } | 8338 } |
| 8350 | 8339 |
| 8351 @override | 8340 @override |
| 8352 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 8341 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 8353 safelyVisit(node.function); | 8342 node.function?.accept(this); |
| 8354 node.accept(elementResolver); | 8343 node.accept(elementResolver); |
| 8355 _inferFunctionExpressionsParametersTypes(node.argumentList); | 8344 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 8356 _inferArgumentTypesFromContext(node); | 8345 _inferArgumentTypesFromContext(node); |
| 8357 safelyVisit(node.argumentList); | 8346 node.argumentList?.accept(this); |
| 8358 node.accept(typeAnalyzer); | 8347 node.accept(typeAnalyzer); |
| 8359 return null; | 8348 return null; |
| 8360 } | 8349 } |
| 8361 | 8350 |
| 8362 @override | 8351 @override |
| 8363 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 8352 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 8364 // Resolve the metadata in the library scope. | 8353 // Resolve the metadata in the library scope. |
| 8365 if (node.metadata != null) { | 8354 if (node.metadata != null) { |
| 8366 node.metadata.accept(this); | 8355 node.metadata.accept(this); |
| 8367 } | 8356 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8380 super.visitFunctionTypeAliasInScope(node); | 8369 super.visitFunctionTypeAliasInScope(node); |
| 8381 safelyVisitComment(node.documentationComment); | 8370 safelyVisitComment(node.documentationComment); |
| 8382 } | 8371 } |
| 8383 | 8372 |
| 8384 @override | 8373 @override |
| 8385 Object visitHideCombinator(HideCombinator node) => null; | 8374 Object visitHideCombinator(HideCombinator node) => null; |
| 8386 | 8375 |
| 8387 @override | 8376 @override |
| 8388 Object visitIfStatement(IfStatement node) { | 8377 Object visitIfStatement(IfStatement node) { |
| 8389 Expression condition = node.condition; | 8378 Expression condition = node.condition; |
| 8390 safelyVisit(condition); | 8379 condition?.accept(this); |
| 8391 Map<VariableElement, DartType> thenOverrides = | 8380 Map<VariableElement, DartType> thenOverrides = |
| 8392 new HashMap<VariableElement, DartType>(); | 8381 new HashMap<VariableElement, DartType>(); |
| 8393 Statement thenStatement = node.thenStatement; | 8382 Statement thenStatement = node.thenStatement; |
| 8394 if (thenStatement != null) { | 8383 if (thenStatement != null) { |
| 8395 _overrideManager.enterScope(); | 8384 _overrideManager.enterScope(); |
| 8396 try { | 8385 try { |
| 8397 _promoteManager.enterScope(); | 8386 _promoteManager.enterScope(); |
| 8398 try { | 8387 try { |
| 8399 _propagateTrueState(condition); | 8388 _propagateTrueState(condition); |
| 8400 // Type promotion. | 8389 // Type promotion. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8460 ClassElement classElement = classTypeName.type.element; | 8449 ClassElement classElement = classTypeName.type.element; |
| 8461 InterfaceType rawType = classElement.type; | 8450 InterfaceType rawType = classElement.type; |
| 8462 InterfaceType fullType = | 8451 InterfaceType fullType = |
| 8463 rawType.substitute2(targs, rawType.typeArguments); | 8452 rawType.substitute2(targs, rawType.typeArguments); |
| 8464 // The element resolver uses the type on the constructor name, so | 8453 // The element resolver uses the type on the constructor name, so |
| 8465 // infer it first | 8454 // infer it first |
| 8466 typeAnalyzer.inferConstructorName(node.constructorName, fullType); | 8455 typeAnalyzer.inferConstructorName(node.constructorName, fullType); |
| 8467 } | 8456 } |
| 8468 } | 8457 } |
| 8469 } | 8458 } |
| 8470 safelyVisit(node.constructorName); | 8459 node.constructorName?.accept(this); |
| 8471 FunctionType constructorType = node.constructorName.staticElement?.type; | 8460 FunctionType constructorType = node.constructorName.staticElement?.type; |
| 8472 if (constructorType != null) { | 8461 if (constructorType != null) { |
| 8473 InferenceContext.setType(node.argumentList, constructorType); | 8462 InferenceContext.setType(node.argumentList, constructorType); |
| 8474 } | 8463 } |
| 8475 safelyVisit(node.argumentList); | 8464 node.argumentList?.accept(this); |
| 8476 node.accept(elementResolver); | 8465 node.accept(elementResolver); |
| 8477 node.accept(typeAnalyzer); | 8466 node.accept(typeAnalyzer); |
| 8478 return null; | 8467 return null; |
| 8479 } | 8468 } |
| 8480 | 8469 |
| 8481 @override | 8470 @override |
| 8482 Object visitLabel(Label node) => null; | 8471 Object visitLabel(Label node) => null; |
| 8483 | 8472 |
| 8484 @override | 8473 @override |
| 8485 Object visitLibraryIdentifier(LibraryIdentifier node) => null; | 8474 Object visitLibraryIdentifier(LibraryIdentifier node) => null; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8559 super.visitMethodDeclarationInScope(node); | 8548 super.visitMethodDeclarationInScope(node); |
| 8560 safelyVisitComment(node.documentationComment); | 8549 safelyVisitComment(node.documentationComment); |
| 8561 } | 8550 } |
| 8562 | 8551 |
| 8563 @override | 8552 @override |
| 8564 Object visitMethodInvocation(MethodInvocation node) { | 8553 Object visitMethodInvocation(MethodInvocation node) { |
| 8565 // | 8554 // |
| 8566 // We visit the target and argument list, but do not visit the method name | 8555 // We visit the target and argument list, but do not visit the method name |
| 8567 // because it needs to be visited in the context of the invocation. | 8556 // because it needs to be visited in the context of the invocation. |
| 8568 // | 8557 // |
| 8569 safelyVisit(node.target); | 8558 node.target?.accept(this); |
| 8570 safelyVisit(node.typeArguments); | 8559 node.typeArguments?.accept(this); |
| 8571 node.accept(elementResolver); | 8560 node.accept(elementResolver); |
| 8572 _inferFunctionExpressionsParametersTypes(node.argumentList); | 8561 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 8573 _inferArgumentTypesFromContext(node); | 8562 _inferArgumentTypesFromContext(node); |
| 8574 safelyVisit(node.argumentList); | 8563 node.argumentList?.accept(this); |
| 8575 node.accept(typeAnalyzer); | 8564 node.accept(typeAnalyzer); |
| 8576 return null; | 8565 return null; |
| 8577 } | 8566 } |
| 8578 | 8567 |
| 8579 @override | 8568 @override |
| 8580 Object visitNamedExpression(NamedExpression node) { | 8569 Object visitNamedExpression(NamedExpression node) { |
| 8581 InferenceContext.setType(node.expression, InferenceContext.getType(node)); | 8570 InferenceContext.setType(node.expression, InferenceContext.getType(node)); |
| 8582 return super.visitNamedExpression(node); | 8571 return super.visitNamedExpression(node); |
| 8583 } | 8572 } |
| 8584 | 8573 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 8595 InferenceContext.setType(node.expression, InferenceContext.getType(node)); | 8584 InferenceContext.setType(node.expression, InferenceContext.getType(node)); |
| 8596 return super.visitParenthesizedExpression(node); | 8585 return super.visitParenthesizedExpression(node); |
| 8597 } | 8586 } |
| 8598 | 8587 |
| 8599 @override | 8588 @override |
| 8600 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 8589 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 8601 // | 8590 // |
| 8602 // We visit the prefix, but do not visit the identifier because it needs to | 8591 // We visit the prefix, but do not visit the identifier because it needs to |
| 8603 // be visited in the context of the prefix. | 8592 // be visited in the context of the prefix. |
| 8604 // | 8593 // |
| 8605 safelyVisit(node.prefix); | 8594 node.prefix?.accept(this); |
| 8606 node.accept(elementResolver); | 8595 node.accept(elementResolver); |
| 8607 node.accept(typeAnalyzer); | 8596 node.accept(typeAnalyzer); |
| 8608 return null; | 8597 return null; |
| 8609 } | 8598 } |
| 8610 | 8599 |
| 8611 @override | 8600 @override |
| 8612 Object visitPropertyAccess(PropertyAccess node) { | 8601 Object visitPropertyAccess(PropertyAccess node) { |
| 8613 // | 8602 // |
| 8614 // We visit the target, but do not visit the property name because it needs | 8603 // We visit the target, but do not visit the property name because it needs |
| 8615 // to be visited in the context of the property access node. | 8604 // to be visited in the context of the property access node. |
| 8616 // | 8605 // |
| 8617 safelyVisit(node.target); | 8606 node.target?.accept(this); |
| 8618 node.accept(elementResolver); | 8607 node.accept(elementResolver); |
| 8619 node.accept(typeAnalyzer); | 8608 node.accept(typeAnalyzer); |
| 8620 return null; | 8609 return null; |
| 8621 } | 8610 } |
| 8622 | 8611 |
| 8623 @override | 8612 @override |
| 8624 Object visitRedirectingConstructorInvocation( | 8613 Object visitRedirectingConstructorInvocation( |
| 8625 RedirectingConstructorInvocation node) { | 8614 RedirectingConstructorInvocation node) { |
| 8626 // | 8615 // |
| 8627 // We visit the argument list, but do not visit the optional identifier | 8616 // We visit the argument list, but do not visit the optional identifier |
| 8628 // because it needs to be visited in the context of the constructor | 8617 // because it needs to be visited in the context of the constructor |
| 8629 // invocation. | 8618 // invocation. |
| 8630 // | 8619 // |
| 8631 InferenceContext.setType(node.argumentList, node.staticElement?.type); | 8620 InferenceContext.setType(node.argumentList, node.staticElement?.type); |
| 8632 safelyVisit(node.argumentList); | 8621 node.argumentList?.accept(this); |
| 8633 node.accept(elementResolver); | 8622 node.accept(elementResolver); |
| 8634 node.accept(typeAnalyzer); | 8623 node.accept(typeAnalyzer); |
| 8635 return null; | 8624 return null; |
| 8636 } | 8625 } |
| 8637 | 8626 |
| 8638 @override | 8627 @override |
| 8639 Object visitReturnStatement(ReturnStatement node) { | 8628 Object visitReturnStatement(ReturnStatement node) { |
| 8640 Expression e = node.expression; | 8629 Expression e = node.expression; |
| 8641 InferenceContext.setType(e, inferenceContext.returnContext); | 8630 InferenceContext.setType(e, inferenceContext.returnContext); |
| 8642 super.visitReturnStatement(node); | 8631 super.visitReturnStatement(node); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 8656 Object visitShowCombinator(ShowCombinator node) => null; | 8645 Object visitShowCombinator(ShowCombinator node) => null; |
| 8657 | 8646 |
| 8658 @override | 8647 @override |
| 8659 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 8648 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 8660 // | 8649 // |
| 8661 // We visit the argument list, but do not visit the optional identifier | 8650 // We visit the argument list, but do not visit the optional identifier |
| 8662 // because it needs to be visited in the context of the constructor | 8651 // because it needs to be visited in the context of the constructor |
| 8663 // invocation. | 8652 // invocation. |
| 8664 // | 8653 // |
| 8665 InferenceContext.setType(node.argumentList, node.staticElement?.type); | 8654 InferenceContext.setType(node.argumentList, node.staticElement?.type); |
| 8666 safelyVisit(node.argumentList); | 8655 node.argumentList?.accept(this); |
| 8667 node.accept(elementResolver); | 8656 node.accept(elementResolver); |
| 8668 node.accept(typeAnalyzer); | 8657 node.accept(typeAnalyzer); |
| 8669 return null; | 8658 return null; |
| 8670 } | 8659 } |
| 8671 | 8660 |
| 8672 @override | 8661 @override |
| 8673 Object visitSwitchCase(SwitchCase node) { | 8662 Object visitSwitchCase(SwitchCase node) { |
| 8674 _overrideManager.enterScope(); | 8663 _overrideManager.enterScope(); |
| 8675 try { | 8664 try { |
| 8676 super.visitSwitchCase(node); | 8665 super.visitSwitchCase(node); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8741 } | 8730 } |
| 8742 | 8731 |
| 8743 @override | 8732 @override |
| 8744 Object visitWhileStatement(WhileStatement node) { | 8733 Object visitWhileStatement(WhileStatement node) { |
| 8745 // Note: since we don't call the base class, we have to maintain | 8734 // Note: since we don't call the base class, we have to maintain |
| 8746 // _implicitLabelScope ourselves. | 8735 // _implicitLabelScope ourselves. |
| 8747 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; | 8736 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; |
| 8748 try { | 8737 try { |
| 8749 _implicitLabelScope = _implicitLabelScope.nest(node); | 8738 _implicitLabelScope = _implicitLabelScope.nest(node); |
| 8750 Expression condition = node.condition; | 8739 Expression condition = node.condition; |
| 8751 safelyVisit(condition); | 8740 condition?.accept(this); |
| 8752 Statement body = node.body; | 8741 Statement body = node.body; |
| 8753 if (body != null) { | 8742 if (body != null) { |
| 8754 _overrideManager.enterScope(); | 8743 _overrideManager.enterScope(); |
| 8755 try { | 8744 try { |
| 8756 _propagateTrueState(condition); | 8745 _propagateTrueState(condition); |
| 8757 visitStatementInScope(body); | 8746 visitStatementInScope(body); |
| 8758 } finally { | 8747 } finally { |
| 8759 _overrideManager.exitScope(); | 8748 _overrideManager.exitScope(); |
| 8760 } | 8749 } |
| 8761 } | 8750 } |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9673 * @param errorCode the error code of the error to be reported | 9662 * @param errorCode the error code of the error to be reported |
| 9674 * @param token the token specifying the location of the error | 9663 * @param token the token specifying the location of the error |
| 9675 * @param arguments the arguments to the error, used to compose the error mess
age | 9664 * @param arguments the arguments to the error, used to compose the error mess
age |
| 9676 */ | 9665 */ |
| 9677 void reportErrorForToken(ErrorCode errorCode, Token token, | 9666 void reportErrorForToken(ErrorCode errorCode, Token token, |
| 9678 [List<Object> arguments]) { | 9667 [List<Object> arguments]) { |
| 9679 errorListener.onError(new AnalysisError( | 9668 errorListener.onError(new AnalysisError( |
| 9680 source, token.offset, token.length, errorCode, arguments)); | 9669 source, token.offset, token.length, errorCode, arguments)); |
| 9681 } | 9670 } |
| 9682 | 9671 |
| 9683 /** | |
| 9684 * Visit the given AST node if it is not null. | |
| 9685 * | |
| 9686 * @param node the node to be visited | |
| 9687 */ | |
| 9688 void safelyVisit(AstNode node) { | |
| 9689 if (node != null) { | |
| 9690 node.accept(this); | |
| 9691 } | |
| 9692 } | |
| 9693 | |
| 9694 @override | 9672 @override |
| 9695 Object visitBlock(Block node) { | 9673 Object visitBlock(Block node) { |
| 9696 Scope outerScope = nameScope; | 9674 Scope outerScope = nameScope; |
| 9697 try { | 9675 try { |
| 9698 EnclosedScope enclosedScope = new EnclosedScope(nameScope); | 9676 EnclosedScope enclosedScope = new EnclosedScope(nameScope); |
| 9699 _hideNamesDefinedInBlock(enclosedScope, node); | 9677 _hideNamesDefinedInBlock(enclosedScope, node); |
| 9700 nameScope = enclosedScope; | 9678 nameScope = enclosedScope; |
| 9701 super.visitBlock(node); | 9679 super.visitBlock(node); |
| 9702 } finally { | 9680 } finally { |
| 9703 nameScope = outerScope; | 9681 nameScope = outerScope; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9761 enclosingClass = outerClass; | 9739 enclosingClass = outerClass; |
| 9762 } | 9740 } |
| 9763 } | 9741 } |
| 9764 } finally { | 9742 } finally { |
| 9765 nameScope = outerScope; | 9743 nameScope = outerScope; |
| 9766 } | 9744 } |
| 9767 return null; | 9745 return null; |
| 9768 } | 9746 } |
| 9769 | 9747 |
| 9770 void visitClassDeclarationInScope(ClassDeclaration node) { | 9748 void visitClassDeclarationInScope(ClassDeclaration node) { |
| 9771 safelyVisit(node.name); | 9749 node.name?.accept(this); |
| 9772 safelyVisit(node.typeParameters); | 9750 node.typeParameters?.accept(this); |
| 9773 safelyVisit(node.extendsClause); | 9751 node.extendsClause?.accept(this); |
| 9774 safelyVisit(node.withClause); | 9752 node.withClause?.accept(this); |
| 9775 safelyVisit(node.implementsClause); | 9753 node.implementsClause?.accept(this); |
| 9776 safelyVisit(node.nativeClause); | 9754 node.nativeClause?.accept(this); |
| 9777 } | 9755 } |
| 9778 | 9756 |
| 9779 void visitClassMembersInScope(ClassDeclaration node) { | 9757 void visitClassMembersInScope(ClassDeclaration node) { |
| 9780 safelyVisit(node.documentationComment); | 9758 node.documentationComment?.accept(this); |
| 9781 node.metadata.accept(this); | 9759 node.metadata.accept(this); |
| 9782 node.members.accept(this); | 9760 node.members.accept(this); |
| 9783 } | 9761 } |
| 9784 | 9762 |
| 9785 @override | 9763 @override |
| 9786 Object visitClassTypeAlias(ClassTypeAlias node) { | 9764 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 9787 Scope outerScope = nameScope; | 9765 Scope outerScope = nameScope; |
| 9788 try { | 9766 try { |
| 9789 ClassElement element = node.element; | 9767 ClassElement element = node.element; |
| 9790 nameScope = | 9768 nameScope = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9836 super.visitDeclaredIdentifier(node); | 9814 super.visitDeclaredIdentifier(node); |
| 9837 return null; | 9815 return null; |
| 9838 } | 9816 } |
| 9839 | 9817 |
| 9840 @override | 9818 @override |
| 9841 Object visitDoStatement(DoStatement node) { | 9819 Object visitDoStatement(DoStatement node) { |
| 9842 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; | 9820 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; |
| 9843 try { | 9821 try { |
| 9844 _implicitLabelScope = _implicitLabelScope.nest(node); | 9822 _implicitLabelScope = _implicitLabelScope.nest(node); |
| 9845 visitStatementInScope(node.body); | 9823 visitStatementInScope(node.body); |
| 9846 safelyVisit(node.condition); | 9824 node.condition?.accept(this); |
| 9847 } finally { | 9825 } finally { |
| 9848 _implicitLabelScope = outerImplicitScope; | 9826 _implicitLabelScope = outerImplicitScope; |
| 9849 } | 9827 } |
| 9850 return null; | 9828 return null; |
| 9851 } | 9829 } |
| 9852 | 9830 |
| 9853 @override | 9831 @override |
| 9854 Object visitEnumDeclaration(EnumDeclaration node) { | 9832 Object visitEnumDeclaration(EnumDeclaration node) { |
| 9855 ClassElement classElement = node.element; | 9833 ClassElement classElement = node.element; |
| 9856 Scope outerScope = nameScope; | 9834 Scope outerScope = nameScope; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 9870 enclosingClass = outerClass; | 9848 enclosingClass = outerClass; |
| 9871 } | 9849 } |
| 9872 } | 9850 } |
| 9873 } finally { | 9851 } finally { |
| 9874 nameScope = outerScope; | 9852 nameScope = outerScope; |
| 9875 } | 9853 } |
| 9876 return null; | 9854 return null; |
| 9877 } | 9855 } |
| 9878 | 9856 |
| 9879 void visitEnumMembersInScope(EnumDeclaration node) { | 9857 void visitEnumMembersInScope(EnumDeclaration node) { |
| 9880 safelyVisit(node.documentationComment); | 9858 node.documentationComment?.accept(this); |
| 9881 node.metadata.accept(this); | 9859 node.metadata.accept(this); |
| 9882 node.constants.accept(this); | 9860 node.constants.accept(this); |
| 9883 } | 9861 } |
| 9884 | 9862 |
| 9885 @override | 9863 @override |
| 9886 Object visitForEachStatement(ForEachStatement node) { | 9864 Object visitForEachStatement(ForEachStatement node) { |
| 9887 Scope outerNameScope = nameScope; | 9865 Scope outerNameScope = nameScope; |
| 9888 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; | 9866 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; |
| 9889 try { | 9867 try { |
| 9890 nameScope = new EnclosedScope(nameScope); | 9868 nameScope = new EnclosedScope(nameScope); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 9902 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is | 9880 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is |
| 9903 * enabled. | 9881 * enabled. |
| 9904 * | 9882 * |
| 9905 * @param node the statement to be visited | 9883 * @param node the statement to be visited |
| 9906 */ | 9884 */ |
| 9907 void visitForEachStatementInScope(ForEachStatement node) { | 9885 void visitForEachStatementInScope(ForEachStatement node) { |
| 9908 // | 9886 // |
| 9909 // We visit the iterator before the loop variable because the loop variable | 9887 // We visit the iterator before the loop variable because the loop variable |
| 9910 // cannot be in scope while visiting the iterator. | 9888 // cannot be in scope while visiting the iterator. |
| 9911 // | 9889 // |
| 9912 safelyVisit(node.identifier); | 9890 node.identifier?.accept(this); |
| 9913 safelyVisit(node.iterable); | 9891 node.iterable?.accept(this); |
| 9914 safelyVisit(node.loopVariable); | 9892 node.loopVariable?.accept(this); |
| 9915 visitStatementInScope(node.body); | 9893 visitStatementInScope(node.body); |
| 9916 } | 9894 } |
| 9917 | 9895 |
| 9918 @override | 9896 @override |
| 9919 Object visitFormalParameterList(FormalParameterList node) { | 9897 Object visitFormalParameterList(FormalParameterList node) { |
| 9920 super.visitFormalParameterList(node); | 9898 super.visitFormalParameterList(node); |
| 9921 // We finished resolving function signature, now include formal parameters | 9899 // We finished resolving function signature, now include formal parameters |
| 9922 // scope. Note: we must not do this if the parent is a | 9900 // scope. Note: we must not do this if the parent is a |
| 9923 // FunctionTypedFormalParameter, because in that case we aren't finished | 9901 // FunctionTypedFormalParameter, because in that case we aren't finished |
| 9924 // resolving the full function signature, just a part of it. | 9902 // resolving the full function signature, just a part of it. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 9948 } | 9926 } |
| 9949 | 9927 |
| 9950 /** | 9928 /** |
| 9951 * Visit the given statement after it's scope has been created. This replaces
the normal call to | 9929 * Visit the given statement after it's scope has been created. This replaces
the normal call to |
| 9952 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is | 9930 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is |
| 9953 * enabled. | 9931 * enabled. |
| 9954 * | 9932 * |
| 9955 * @param node the statement to be visited | 9933 * @param node the statement to be visited |
| 9956 */ | 9934 */ |
| 9957 void visitForStatementInScope(ForStatement node) { | 9935 void visitForStatementInScope(ForStatement node) { |
| 9958 safelyVisit(node.variables); | 9936 node.variables?.accept(this); |
| 9959 safelyVisit(node.initialization); | 9937 node.initialization?.accept(this); |
| 9960 safelyVisit(node.condition); | 9938 node.condition?.accept(this); |
| 9961 node.updaters.accept(this); | 9939 node.updaters.accept(this); |
| 9962 visitStatementInScope(node.body); | 9940 visitStatementInScope(node.body); |
| 9963 } | 9941 } |
| 9964 | 9942 |
| 9965 @override | 9943 @override |
| 9966 Object visitFunctionDeclaration(FunctionDeclaration node) { | 9944 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 9967 ExecutableElement functionElement = node.element; | 9945 ExecutableElement functionElement = node.element; |
| 9968 if (functionElement != null && | 9946 if (functionElement != null && |
| 9969 functionElement.enclosingElement is! CompilationUnitElement) { | 9947 functionElement.enclosingElement is! CompilationUnitElement) { |
| 9970 nameScope.define(functionElement); | 9948 nameScope.define(functionElement); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10060 } | 10038 } |
| 10061 super.visitFunctionTypedFormalParameter(node); | 10039 super.visitFunctionTypedFormalParameter(node); |
| 10062 } finally { | 10040 } finally { |
| 10063 nameScope = outerScope; | 10041 nameScope = outerScope; |
| 10064 } | 10042 } |
| 10065 return null; | 10043 return null; |
| 10066 } | 10044 } |
| 10067 | 10045 |
| 10068 @override | 10046 @override |
| 10069 Object visitIfStatement(IfStatement node) { | 10047 Object visitIfStatement(IfStatement node) { |
| 10070 safelyVisit(node.condition); | 10048 node.condition?.accept(this); |
| 10071 visitStatementInScope(node.thenStatement); | 10049 visitStatementInScope(node.thenStatement); |
| 10072 visitStatementInScope(node.elseStatement); | 10050 visitStatementInScope(node.elseStatement); |
| 10073 return null; | 10051 return null; |
| 10074 } | 10052 } |
| 10075 | 10053 |
| 10076 @override | 10054 @override |
| 10077 Object visitLabeledStatement(LabeledStatement node) { | 10055 Object visitLabeledStatement(LabeledStatement node) { |
| 10078 LabelScope outerScope = _addScopesFor(node.labels, node.unlabeled); | 10056 LabelScope outerScope = _addScopesFor(node.labels, node.unlabeled); |
| 10079 try { | 10057 try { |
| 10080 super.visitLabeledStatement(node); | 10058 super.visitLabeledStatement(node); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10184 VariableElement element = node.element; | 10162 VariableElement element = node.element; |
| 10185 if (element != null) { | 10163 if (element != null) { |
| 10186 nameScope.define(element); | 10164 nameScope.define(element); |
| 10187 } | 10165 } |
| 10188 } | 10166 } |
| 10189 return null; | 10167 return null; |
| 10190 } | 10168 } |
| 10191 | 10169 |
| 10192 @override | 10170 @override |
| 10193 Object visitWhileStatement(WhileStatement node) { | 10171 Object visitWhileStatement(WhileStatement node) { |
| 10194 safelyVisit(node.condition); | 10172 node.condition?.accept(this); |
| 10195 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; | 10173 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; |
| 10196 try { | 10174 try { |
| 10197 _implicitLabelScope = _implicitLabelScope.nest(node); | 10175 _implicitLabelScope = _implicitLabelScope.nest(node); |
| 10198 visitStatementInScope(node.body); | 10176 visitStatementInScope(node.body); |
| 10199 } finally { | 10177 } finally { |
| 10200 _implicitLabelScope = outerImplicitScope; | 10178 _implicitLabelScope = outerImplicitScope; |
| 10201 } | 10179 } |
| 10202 return null; | 10180 return null; |
| 10203 } | 10181 } |
| 10204 | 10182 |
| (...skipping 2768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12973 nonFields.add(node); | 12951 nonFields.add(node); |
| 12974 return null; | 12952 return null; |
| 12975 } | 12953 } |
| 12976 | 12954 |
| 12977 @override | 12955 @override |
| 12978 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 12956 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 12979 | 12957 |
| 12980 @override | 12958 @override |
| 12981 Object visitWithClause(WithClause node) => null; | 12959 Object visitWithClause(WithClause node) => null; |
| 12982 } | 12960 } |
| OLD | NEW |