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

Side by Side Diff: pkg/analyzer/test/src/task/dart_test.dart

Issue 1147853002: Properly handle circular references among constants in the task model. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 7 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 library test.src.task.dart_test; 5 library test.src.task.dart_test;
6 6
7 import 'package:analyzer/src/context/cache.dart'; 7 import 'package:analyzer/src/context/cache.dart';
8 import 'package:analyzer/src/generated/ast.dart'; 8 import 'package:analyzer/src/generated/ast.dart';
9 import 'package:analyzer/src/generated/constant.dart'; 9 import 'package:analyzer/src/generated/constant.dart';
10 import 'package:analyzer/src/generated/element.dart'; 10 import 'package:analyzer/src/generated/element.dart';
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 expect(outputs[CONSTANT_VALUE], same(target)); 1305 expect(outputs[CONSTANT_VALUE], same(target));
1306 EvaluationResultImpl evaluationResult = 1306 EvaluationResultImpl evaluationResult =
1307 (annotation.elementAnnotation as ElementAnnotationImpl).evaluationRe sult; 1307 (annotation.elementAnnotation as ElementAnnotationImpl).evaluationRe sult;
1308 return evaluationResult; 1308 return evaluationResult;
1309 } 1309 }
1310 } 1310 }
1311 fail('Annotation not found'); 1311 fail('Annotation not found');
1312 return null; 1312 return null;
1313 } 1313 }
1314 1314
1315 fail_circular_reference() { 1315 fail_circular_reference_one_element() {
1316 // TODO(paulberry): get this to work. 1316 // See dartbug.com/23490.
1317 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( 1317 _checkCircularities('x', [], 'const x = x;');
1318 'x', '''
1319 const x = y + 1;
1320 const y = x + 1;
1321 ''');
1322 expect(evaluationResult, isNotNull);
1323 expect(evaluationResult.value, isNull);
1324 expect(evaluationResult.errors, hasLength(1));
1325 expect(evaluationResult.errors[0].errorCode,
1326 CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT);
1327 } 1318 }
1328 1319
1329 test_annotation_with_args() { 1320 test_annotation_with_args() {
1330 Source source = newSource('/test.dart', ''' 1321 Source source = newSource('/test.dart', '''
1331 const x = 1; 1322 const x = 1;
1332 @D(x) class C {} 1323 @D(x) class C {}
1333 class D { 1324 class D {
1334 const D(this.value); 1325 const D(this.value);
1335 final value; 1326 final value;
1336 } 1327 }
(...skipping 27 matching lines...) Expand all
1364 CompilationUnit unit = outputs[RESOLVED_UNIT1]; 1355 CompilationUnit unit = outputs[RESOLVED_UNIT1];
1365 // Compute the constant value of the annotation on C. 1356 // Compute the constant value of the annotation on C.
1366 EvaluationResultImpl evaluationResult = 1357 EvaluationResultImpl evaluationResult =
1367 computeClassAnnotation(source, unit, 'C'); 1358 computeClassAnnotation(source, unit, 'C');
1368 // And check that it has the expected value. 1359 // And check that it has the expected value.
1369 expect(evaluationResult, isNotNull); 1360 expect(evaluationResult, isNotNull);
1370 expect(evaluationResult.value, isNotNull); 1361 expect(evaluationResult.value, isNotNull);
1371 expect(evaluationResult.value.intValue, 1); 1362 expect(evaluationResult.value.intValue, 1);
1372 } 1363 }
1373 1364
1365 test_circular_reference() {
1366 _checkCircularities('x', ['y'], '''
1367 const x = y + 1;
1368 const y = x + 1;
1369 ''');
1370 }
1371
1372 test_circular_reference_strongly_connected_component() {
1373 // When there is a circularity, all elements in the strongly connected
1374 // component should be marked as having an error.
1375 _checkCircularities('a', ['b', 'c', 'd'], '''
1376 const a = b;
1377 const b = c + d;
1378 const c = a;
1379 const d = a;
1380 ''');
1381 }
1382
1374 test_dependency() { 1383 test_dependency() {
1375 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( 1384 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
1376 'x', ''' 1385 'x', '''
1377 const x = y + 1; 1386 const x = y + 1;
1378 const y = 1; 1387 const y = 1;
1379 '''); 1388 ''');
1380 expect(evaluationResult, isNotNull); 1389 expect(evaluationResult, isNotNull);
1381 expect(evaluationResult.value, isNotNull); 1390 expect(evaluationResult.value, isNotNull);
1382 expect(evaluationResult.value.intValue, 2); 1391 expect(evaluationResult.value.intValue, 2);
1383 } 1392 }
(...skipping 15 matching lines...) Expand all
1399 test_simple_constant() { 1408 test_simple_constant() {
1400 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( 1409 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
1401 'x', ''' 1410 'x', '''
1402 const x = 1; 1411 const x = 1;
1403 '''); 1412 ''');
1404 expect(evaluationResult, isNotNull); 1413 expect(evaluationResult, isNotNull);
1405 expect(evaluationResult.value, isNotNull); 1414 expect(evaluationResult.value, isNotNull);
1406 expect(evaluationResult.value.intValue, 1); 1415 expect(evaluationResult.value.intValue, 1);
1407 } 1416 }
1408 1417
1418 void _checkCircularities(
1419 String variableName, List<String> otherVariables, String content) {
1420 // Evaluating the first constant should produce an error.
1421 CompilationUnit unit = _resolveUnit(content);
1422 _expectCircularityError(_evaluateConstant(unit, variableName));
1423 // And all the other constants involved in the strongly connected component
1424 // should be set to the same error state.
1425 for (String otherVariableName in otherVariables) {
1426 PropertyInducingElement otherVariableElement =
1427 _findVariable(unit, otherVariableName);
1428 _expectCircularityError(
1429 (otherVariableElement as TopLevelVariableElementImpl).evaluationResult );
1430 }
1431 }
1432
1409 EvaluationResultImpl _computeTopLevelVariableConstValue( 1433 EvaluationResultImpl _computeTopLevelVariableConstValue(
1410 String variableName, String content) { 1434 String variableName, String content) {
1411 Source source = newSource('/test.dart', content); 1435 return _evaluateConstant(_resolveUnit(content), variableName);
1412 // First compute the resolved unit for the source. 1436 }
1413 LibrarySpecificUnit librarySpecificUnit = 1437
1414 new LibrarySpecificUnit(source, source); 1438 EvaluationResultImpl _evaluateConstant(
1415 _computeResult(librarySpecificUnit, RESOLVED_UNIT1); 1439 CompilationUnit unit, String variableName) {
1416 CompilationUnit unit = outputs[RESOLVED_UNIT1];
1417 // Find the element for the given constant. 1440 // Find the element for the given constant.
1418 List<PropertyAccessorElement> accessors = unit.element.accessors; 1441 PropertyInducingElement variableElement = _findVariable(unit, variableName);
1419 Element variableElement = accessors
1420 .firstWhere((PropertyAccessorElement accessor) {
1421 return accessor.isGetter && accessor.name == variableName;
1422 }).variable;
1423 // Now compute the value of the constant. 1442 // Now compute the value of the constant.
1424 _computeResult(variableElement, CONSTANT_VALUE); 1443 _computeResult(variableElement, CONSTANT_VALUE);
1425 expect(outputs[CONSTANT_VALUE], same(variableElement)); 1444 expect(outputs[CONSTANT_VALUE], same(variableElement));
1426 EvaluationResultImpl evaluationResult = 1445 EvaluationResultImpl evaluationResult =
1427 (variableElement as TopLevelVariableElementImpl).evaluationResult; 1446 (variableElement as TopLevelVariableElementImpl).evaluationResult;
1428 return evaluationResult; 1447 return evaluationResult;
1429 } 1448 }
1449
1450 void _expectCircularityError(EvaluationResultImpl evaluationResult) {
1451 expect(evaluationResult, isNotNull);
1452 expect(evaluationResult.value, isNull);
1453 expect(evaluationResult.errors, hasLength(1));
1454 expect(evaluationResult.errors[0].errorCode,
1455 CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT);
1456 }
1457
1458 PropertyInducingElement _findVariable(
1459 CompilationUnit unit, String variableName) {
1460 // Find the element for the given constant.
1461 List<PropertyAccessorElement> accessors = unit.element.accessors;
1462 Element variableElement = accessors
1463 .firstWhere((PropertyAccessorElement accessor) {
1464 return accessor.isGetter && accessor.name == variableName;
1465 }).variable;
scheglov 2015/05/19 19:25:41 You could use unit.element.topLevelVariables direc
Paul Berry 2015/05/19 19:36:11 Done.
1466 return variableElement;
1467 }
1468
1469 CompilationUnit _resolveUnit(String content) {
1470 Source source = newSource('/test.dart', content);
1471 // First compute the resolved unit for the source.
1472 LibrarySpecificUnit librarySpecificUnit =
1473 new LibrarySpecificUnit(source, source);
1474 _computeResult(librarySpecificUnit, RESOLVED_UNIT1);
1475 CompilationUnit unit = outputs[RESOLVED_UNIT1];
1476 return unit;
1477 }
1430 } 1478 }
1431 1479
1432 @reflectiveTest 1480 @reflectiveTest
1433 class ContainingLibrariesTaskTest extends _AbstractDartTaskTest { 1481 class ContainingLibrariesTaskTest extends _AbstractDartTaskTest {
1434 test_buildInputs() { 1482 test_buildInputs() {
1435 Map<String, TaskInput> inputs = 1483 Map<String, TaskInput> inputs =
1436 ContainingLibrariesTask.buildInputs(emptySource); 1484 ContainingLibrariesTask.buildInputs(emptySource);
1437 expect(inputs, isNotNull); 1485 expect(inputs, isNotNull);
1438 expect(inputs, isEmpty); 1486 expect(inputs, isEmpty);
1439 } 1487 }
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
2413 /** 2461 /**
2414 * Fill [errorListener] with [result] errors in the current [task]. 2462 * Fill [errorListener] with [result] errors in the current [task].
2415 */ 2463 */
2416 void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) { 2464 void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) {
2417 List<AnalysisError> errors = task.outputs[result]; 2465 List<AnalysisError> errors = task.outputs[result];
2418 expect(errors, isNotNull, reason: result.name); 2466 expect(errors, isNotNull, reason: result.name);
2419 errorListener = new GatheringErrorListener(); 2467 errorListener = new GatheringErrorListener();
2420 errorListener.addAll(errors); 2468 errorListener.addAll(errors);
2421 } 2469 }
2422 } 2470 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698