OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013, the Dart project authors. | 2 * Copyright (c) 2013, the Dart project authors. |
3 * | 3 * |
4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except | 4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except |
5 * in compliance with the License. You may obtain a copy of the License at | 5 * in compliance with the License. You may obtain a copy of the License at |
6 * | 6 * |
7 * http://www.eclipse.org/legal/epl-v10.html | 7 * http://www.eclipse.org/legal/epl-v10.html |
8 * | 8 * |
9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License | 9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License |
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express | 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 safelyVisit(leftOperand); | 237 safelyVisit(leftOperand); |
238 if (rightOperand != null) { | 238 if (rightOperand != null) { |
239 try { | 239 try { |
240 overrideManager.enterScope(); | 240 overrideManager.enterScope(); |
241 promoteManager.enterScope(); | 241 promoteManager.enterScope(); |
242 propagateTrueState(leftOperand); | 242 propagateTrueState(leftOperand); |
243 // Type promotion. | 243 // Type promotion. |
244 promoteTypes(leftOperand); | 244 promoteTypes(leftOperand); |
245 clearTypePromotionsIfPotentiallyMutatedIn(leftOperand); | 245 clearTypePromotionsIfPotentiallyMutatedIn(leftOperand); |
246 clearTypePromotionsIfPotentiallyMutatedIn(rightOperand); | 246 clearTypePromotionsIfPotentiallyMutatedIn(rightOperand); |
247 clearTypePromotionsIfAccessedInScopeAndProtentiallyMutated(rightOperan
d); | 247 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(rightOper
and); |
248 // Visit right operand. | 248 // Visit right operand. |
249 rightOperand.accept(this); | 249 rightOperand.accept(this); |
250 } finally { | 250 } finally { |
251 overrideManager.exitScope(); | 251 overrideManager.exitScope(); |
252 promoteManager.exitScope(); | 252 promoteManager.exitScope(); |
253 } | 253 } |
254 } | 254 } |
255 } else if (operatorType == TokenType.BAR_BAR) { | 255 } else if (operatorType == TokenType.BAR_BAR) { |
256 safelyVisit(leftOperand); | 256 safelyVisit(leftOperand); |
257 if (rightOperand != null) { | 257 if (rightOperand != null) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 safelyVisit(condition); | 357 safelyVisit(condition); |
358 Expression thenExpression = node.getThenExpression(); | 358 Expression thenExpression = node.getThenExpression(); |
359 if (thenExpression != null) { | 359 if (thenExpression != null) { |
360 try { | 360 try { |
361 overrideManager.enterScope(); | 361 overrideManager.enterScope(); |
362 promoteManager.enterScope(); | 362 promoteManager.enterScope(); |
363 propagateTrueState(condition); | 363 propagateTrueState(condition); |
364 // Type promotion. | 364 // Type promotion. |
365 promoteTypes(condition); | 365 promoteTypes(condition); |
366 clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); | 366 clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); |
367 clearTypePromotionsIfAccessedInScopeAndProtentiallyMutated(thenExpressio
n); | 367 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenExpress
ion); |
368 // Visit "then" expression. | 368 // Visit "then" expression. |
369 thenExpression.accept(this); | 369 thenExpression.accept(this); |
370 } finally { | 370 } finally { |
371 overrideManager.exitScope(); | 371 overrideManager.exitScope(); |
372 promoteManager.exitScope(); | 372 promoteManager.exitScope(); |
373 } | 373 } |
374 } | 374 } |
375 Expression elseExpression = node.getElseExpression(); | 375 Expression elseExpression = node.getElseExpression(); |
376 if (elseExpression != null) { | 376 if (elseExpression != null) { |
377 try { | 377 try { |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 HashMap<Element, Type> thenOverrides = null; | 565 HashMap<Element, Type> thenOverrides = null; |
566 Statement thenStatement = node.getThenStatement(); | 566 Statement thenStatement = node.getThenStatement(); |
567 if (thenStatement != null) { | 567 if (thenStatement != null) { |
568 try { | 568 try { |
569 overrideManager.enterScope(); | 569 overrideManager.enterScope(); |
570 promoteManager.enterScope(); | 570 promoteManager.enterScope(); |
571 propagateTrueState(condition); | 571 propagateTrueState(condition); |
572 // Type promotion. | 572 // Type promotion. |
573 promoteTypes(condition); | 573 promoteTypes(condition); |
574 clearTypePromotionsIfPotentiallyMutatedIn(thenStatement); | 574 clearTypePromotionsIfPotentiallyMutatedIn(thenStatement); |
575 clearTypePromotionsIfAccessedInScopeAndProtentiallyMutated(thenStatement
); | 575 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenStateme
nt); |
576 // Visit "then". | 576 // Visit "then". |
577 visitStatementInScope(thenStatement); | 577 visitStatementInScope(thenStatement); |
578 } finally { | 578 } finally { |
579 thenOverrides = overrideManager.captureLocalOverrides(); | 579 thenOverrides = overrideManager.captureLocalOverrides(); |
580 overrideManager.exitScope(); | 580 overrideManager.exitScope(); |
581 promoteManager.exitScope(); | 581 promoteManager.exitScope(); |
582 } | 582 } |
583 } | 583 } |
584 HashMap<Element, Type> elseOverrides = null; | 584 HashMap<Element, Type> elseOverrides = null; |
585 Statement elseStatement = node.getElseStatement(); | 585 Statement elseStatement = node.getElseStatement(); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 return; | 916 return; |
917 } | 917 } |
918 } | 918 } |
919 Type currentType = getBestType(element); | 919 Type currentType = getBestType(element); |
920 if (currentType == null || !currentType.isMoreSpecificThan(potentialType)) { | 920 if (currentType == null || !currentType.isMoreSpecificThan(potentialType)) { |
921 overrideManager.setType(element, potentialType); | 921 overrideManager.setType(element, potentialType); |
922 } | 922 } |
923 } | 923 } |
924 | 924 |
925 /** | 925 /** |
926 * If it is appropriate to do so, promotes the current type of the static elem
ent associated with | |
927 * the given expression with the given type. Generally speaking, it is appropr
iate if the given | |
928 * type is more specific than the current type. | |
929 * | |
930 * @param expression the expression used to access the static element whose ty
pes might be | |
931 * promoted | |
932 * @param potentialType the potential type of the elements | |
933 */ | |
934 protected void promote(Expression expression, Type potentialType) { | |
935 VariableElement element = getPromotionStaticElement(expression); | |
936 if (element != null) { | |
937 // may be mutated somewhere in closure | |
938 if (((VariableElementImpl) element).isPotentiallyMutatedInClosure()) { | |
939 return; | |
940 } | |
941 // prepare current variable type | |
942 Type type = expression.getStaticType(); | |
943 // Declared type should not be "dynamic". | |
944 if (type == null || type.isDynamic()) { | |
945 return; | |
946 } | |
947 // Promoted type should not be "dynamic". | |
948 if (potentialType == null || potentialType.isDynamic()) { | |
949 return; | |
950 } | |
951 // Promoted type should be more specific than declared. | |
952 if (!potentialType.isMoreSpecificThan(type)) { | |
953 return; | |
954 } | |
955 // Do promote type of variable. | |
956 promoteManager.setType(element, potentialType); | |
957 } | |
958 } | |
959 | |
960 /** | |
961 * Report a conditional analysis error with the given error code and arguments
. | 926 * Report a conditional analysis error with the given error code and arguments
. |
962 * | 927 * |
963 * @param enclosingElement the enclosing element | 928 * @param enclosingElement the enclosing element |
964 * @param errorCode the error code of the error to be reported | 929 * @param errorCode the error code of the error to be reported |
965 * @param node the node specifying the location of the error | 930 * @param node the node specifying the location of the error |
966 * @param arguments the arguments to the error, used to compose the error mess
age | 931 * @param arguments the arguments to the error, used to compose the error mess
age |
967 */ | 932 */ |
968 protected void reportErrorProxyConditionalAnalysisError(Element enclosingEleme
nt, | 933 protected void reportErrorProxyConditionalAnalysisError(Element enclosingEleme
nt, |
969 ErrorCode errorCode, ASTNode node, Object... arguments) { | 934 ErrorCode errorCode, ASTNode node, Object... arguments) { |
970 proxyConditionalAnalysisErrors.add(new ProxyConditionalAnalysisError( | 935 proxyConditionalAnalysisErrors.add(new ProxyConditionalAnalysisError( |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 // propagateFalseState(condition); | 1025 // propagateFalseState(condition); |
1061 } | 1026 } |
1062 | 1027 |
1063 /** | 1028 /** |
1064 * Checks each promoted variable in the current scope for compliance with the
following | 1029 * Checks each promoted variable in the current scope for compliance with the
following |
1065 * specification statement: | 1030 * specification statement: |
1066 * <p> | 1031 * <p> |
1067 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t
hen the variable | 1032 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t
hen the variable |
1068 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. | 1033 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. |
1069 */ | 1034 */ |
1070 private void clearTypePromotionsIfAccessedInScopeAndProtentiallyMutated(ASTNod
e target) { | 1035 private void clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(ASTN
ode target) { |
1071 for (Element element : promoteManager.getPromotedElements()) { | 1036 for (Element element : promoteManager.getPromotedElements()) { |
1072 if (((VariableElementImpl) element).isPotentiallyMutatedInScope()) { | 1037 if (((VariableElementImpl) element).isPotentiallyMutatedInScope()) { |
1073 if (isVariableAccessedInClosure(element, target)) { | 1038 if (isVariableAccessedInClosure(element, target)) { |
1074 promoteManager.setType(element, null); | 1039 promoteManager.setType(element, null); |
1075 } | 1040 } |
1076 } | 1041 } |
1077 } | 1042 } |
1078 } | 1043 } |
1079 | 1044 |
1080 /** | 1045 /** |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1295 result[0] |= true; | 1260 result[0] |= true; |
1296 } | 1261 } |
1297 } | 1262 } |
1298 return null; | 1263 return null; |
1299 } | 1264 } |
1300 }); | 1265 }); |
1301 return result[0]; | 1266 return result[0]; |
1302 } | 1267 } |
1303 | 1268 |
1304 /** | 1269 /** |
| 1270 * If it is appropriate to do so, promotes the current type of the static elem
ent associated with |
| 1271 * the given expression with the given type. Generally speaking, it is appropr
iate if the given |
| 1272 * type is more specific than the current type. |
| 1273 * |
| 1274 * @param expression the expression used to access the static element whose ty
pes might be |
| 1275 * promoted |
| 1276 * @param potentialType the potential type of the elements |
| 1277 */ |
| 1278 private void promote(Expression expression, Type potentialType) { |
| 1279 VariableElement element = getPromotionStaticElement(expression); |
| 1280 if (element != null) { |
| 1281 // may be mutated somewhere in closure |
| 1282 if (((VariableElementImpl) element).isPotentiallyMutatedInClosure()) { |
| 1283 return; |
| 1284 } |
| 1285 // prepare current variable type |
| 1286 Type type = promoteManager.getType(element); |
| 1287 if (type == null) { |
| 1288 type = expression.getStaticType(); |
| 1289 } |
| 1290 // Declared type should not be "dynamic". |
| 1291 if (type == null || type.isDynamic()) { |
| 1292 return; |
| 1293 } |
| 1294 // Promoted type should not be "dynamic". |
| 1295 if (potentialType == null || potentialType.isDynamic()) { |
| 1296 return; |
| 1297 } |
| 1298 // Promoted type should be more specific than declared. |
| 1299 if (!potentialType.isMoreSpecificThan(type)) { |
| 1300 return; |
| 1301 } |
| 1302 // Do promote type of variable. |
| 1303 promoteManager.setType(element, potentialType); |
| 1304 } |
| 1305 } |
| 1306 |
| 1307 /** |
1305 * Promotes type information using given condition. | 1308 * Promotes type information using given condition. |
1306 */ | 1309 */ |
1307 private void promoteTypes(Expression condition) { | 1310 private void promoteTypes(Expression condition) { |
1308 if (condition instanceof BinaryExpression) { | 1311 if (condition instanceof BinaryExpression) { |
1309 BinaryExpression binary = (BinaryExpression) condition; | 1312 BinaryExpression binary = (BinaryExpression) condition; |
1310 if (binary.getOperator().getType() == TokenType.AMPERSAND_AMPERSAND) { | 1313 if (binary.getOperator().getType() == TokenType.AMPERSAND_AMPERSAND) { |
1311 Expression left = binary.getLeftOperand(); | 1314 Expression left = binary.getLeftOperand(); |
1312 Expression right = binary.getRightOperand(); | 1315 Expression right = binary.getRightOperand(); |
1313 promoteTypes(left); | 1316 promoteTypes(left); |
1314 promoteTypes(right); | 1317 promoteTypes(right); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1395 * | 1398 * |
1396 * @param expression the node whose type is to be recorded | 1399 * @param expression the node whose type is to be recorded |
1397 * @param type the propagated type of the node | 1400 * @param type the propagated type of the node |
1398 */ | 1401 */ |
1399 private void recordPropagatedType(Expression expression, Type type) { | 1402 private void recordPropagatedType(Expression expression, Type type) { |
1400 if (type != null && !type.isDynamic()) { | 1403 if (type != null && !type.isDynamic()) { |
1401 expression.setPropagatedType(type); | 1404 expression.setPropagatedType(type); |
1402 } | 1405 } |
1403 } | 1406 } |
1404 } | 1407 } |
OLD | NEW |