| 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.constant; | 5 library analyzer.src.generated.constant; |
| 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/visitor.dart'; | 10 import 'package:analyzer/dart/ast/visitor.dart'; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 */ | 230 */ |
| 231 static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp( | 231 static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp( |
| 232 "^(?:${ConstantValueComputer._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$
|[.](?!\$)))+?\$"); | 232 "^(?:${ConstantValueComputer._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$
|[.](?!\$)))+?\$"); |
| 233 | 233 |
| 234 /** | 234 /** |
| 235 * The type provider used to access the known types. | 235 * The type provider used to access the known types. |
| 236 */ | 236 */ |
| 237 final TypeProvider typeProvider; | 237 final TypeProvider typeProvider; |
| 238 | 238 |
| 239 /** | 239 /** |
| 240 * The type system. This is used to gues the types of constants when their | 240 * The type system. This is used to guess the types of constants when their |
| 241 * exact value is unknown. | 241 * exact value is unknown. |
| 242 */ | 242 */ |
| 243 final TypeSystem typeSystem; | 243 final TypeSystem typeSystem; |
| 244 | 244 |
| 245 /** | 245 /** |
| 246 * The set of variables declared on the command line using '-D'. | 246 * The set of variables declared on the command line using '-D'. |
| 247 */ | 247 */ |
| 248 final DeclaredVariables _declaredVariables; | 248 final DeclaredVariables _declaredVariables; |
| 249 | 249 |
| 250 /** | 250 /** |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 new EvaluationResultImpl(result, errorListener.errors); | 419 new EvaluationResultImpl(result, errorListener.errors); |
| 420 } else { | 420 } else { |
| 421 // This may happen for invalid code (e.g. failing to pass arguments | 421 // This may happen for invalid code (e.g. failing to pass arguments |
| 422 // to an annotation which references a const constructor). The error | 422 // to an annotation which references a const constructor). The error |
| 423 // is detected elsewhere, so just silently ignore it here. | 423 // is detected elsewhere, so just silently ignore it here. |
| 424 constant.evaluationResult = new EvaluationResultImpl(null); | 424 constant.evaluationResult = new EvaluationResultImpl(null); |
| 425 } | 425 } |
| 426 } else if (constant is VariableElement) { | 426 } else if (constant is VariableElement) { |
| 427 // constant is a VariableElement but not a VariableElementImpl. This can | 427 // constant is a VariableElement but not a VariableElementImpl. This can |
| 428 // happen sometimes in the case of invalid user code (for example, a | 428 // happen sometimes in the case of invalid user code (for example, a |
| 429 // constant expression that refers to a nonstatic field inside a generic | 429 // constant expression that refers to a non-static field inside a generic |
| 430 // class will wind up referring to a FieldMember). The error is detected | 430 // class will wind up referring to a FieldMember). The error is detected |
| 431 // elsewhere, so just silently ignore it here. | 431 // elsewhere, so just silently ignore it here. |
| 432 } else { | 432 } else { |
| 433 // Should not happen. | 433 // Should not happen. |
| 434 assert(false); | 434 assert(false); |
| 435 AnalysisEngine.instance.logger.logError( | 435 AnalysisEngine.instance.logger.logError( |
| 436 "Constant value computer trying to compute the value of a node of type
${constant.runtimeType}"); | 436 "Constant value computer trying to compute the value of a node of type
${constant.runtimeType}"); |
| 437 return; | 437 return; |
| 438 } | 438 } |
| 439 } | 439 } |
| 440 | 440 |
| 441 /** | 441 /** |
| 442 * Determine which constant elements need to have their values computed | 442 * Determine which constant elements need to have their values computed |
| 443 * prior to computing the value of [constant], and report them using | 443 * prior to computing the value of [constant], and report them using |
| 444 * [callback]. | 444 * [callback]. |
| 445 */ | 445 */ |
| 446 void computeDependencies( | 446 void computeDependencies( |
| 447 ConstantEvaluationTarget constant, ReferenceFinderCallback callback) { | 447 ConstantEvaluationTarget constant, ReferenceFinderCallback callback) { |
| 448 ReferenceFinder referenceFinder = new ReferenceFinder(callback); | 448 ReferenceFinder referenceFinder = new ReferenceFinder(callback); |
| 449 if (constant is ParameterElementImpl) { | 449 if (constant is VariableElementImpl) { |
| 450 if (constant.initializer != null) { | |
| 451 Expression defaultValue = constant.constantInitializer; | |
| 452 if (defaultValue != null) { | |
| 453 defaultValue.accept(referenceFinder); | |
| 454 } | |
| 455 } | |
| 456 } else if (constant is VariableElementImpl) { | |
| 457 Expression initializer = constant.constantInitializer; | 450 Expression initializer = constant.constantInitializer; |
| 458 if (initializer != null) { | 451 if (initializer != null) { |
| 459 initializer.accept(referenceFinder); | 452 initializer.accept(referenceFinder); |
| 460 } | 453 } |
| 461 } else if (constant is ConstructorElementImpl) { | 454 } else if (constant is ConstructorElementImpl) { |
| 462 if (constant.isConst) { | 455 if (constant.isConst) { |
| 463 constant.isCycleFree = false; | 456 constant.isCycleFree = false; |
| 464 ConstructorElement redirectedConstructor = | 457 ConstructorElement redirectedConstructor = |
| 465 getConstRedirectedConstructor(constant); | 458 getConstRedirectedConstructor(constant); |
| 466 if (redirectedConstructor != null) { | 459 if (redirectedConstructor != null) { |
| 467 ConstructorElement redirectedConstructorBase = | 460 ConstructorElement redirectedConstructorBase = |
| 468 ConstantEvaluationEngine | 461 _getConstructorBase(redirectedConstructor); |
| 469 ._getConstructorBase(redirectedConstructor); | |
| 470 callback(redirectedConstructorBase); | 462 callback(redirectedConstructorBase); |
| 471 return; | 463 return; |
| 472 } else if (constant.isFactory) { | 464 } else if (constant.isFactory) { |
| 473 // Factory constructor, but getConstRedirectedConstructor returned | 465 // Factory constructor, but getConstRedirectedConstructor returned |
| 474 // null. This can happen if we're visiting one of the special externa
l | 466 // null. This can happen if we're visiting one of the special externa
l |
| 475 // const factory constructors in the SDK, or if the code contains | 467 // const factory constructors in the SDK, or if the code contains |
| 476 // errors (such as delegating to a non-const constructor, or delegatin
g | 468 // errors (such as delegating to a non-const constructor, or delegatin
g |
| 477 // to a constructor that can't be resolved). In any of these cases, | 469 // to a constructor that can't be resolved). In any of these cases, |
| 478 // we'll evaluate calls to this constructor without having to refer to | 470 // we'll evaluate calls to this constructor without having to refer to |
| 479 // any other constants. So we don't need to report any dependencies. | 471 // any other constants. So we don't need to report any dependencies. |
| 480 return; | 472 return; |
| 481 } | 473 } |
| 482 bool superInvocationFound = false; | 474 bool superInvocationFound = false; |
| 483 List<ConstructorInitializer> initializers = | 475 List<ConstructorInitializer> initializers = |
| 484 constant.constantInitializers; | 476 constant.constantInitializers; |
| 485 for (ConstructorInitializer initializer in initializers) { | 477 for (ConstructorInitializer initializer in initializers) { |
| 486 if (initializer is SuperConstructorInvocation) { | 478 if (initializer is SuperConstructorInvocation) { |
| 487 superInvocationFound = true; | 479 superInvocationFound = true; |
| 488 } | 480 } |
| 489 initializer.accept(referenceFinder); | 481 initializer.accept(referenceFinder); |
| 490 } | 482 } |
| 491 if (!superInvocationFound) { | 483 if (!superInvocationFound) { |
| 492 // No explicit superconstructor invocation found, so we need to | 484 // No explicit superconstructor invocation found, so we need to |
| 493 // manually insert a reference to the implicit superconstructor. | 485 // manually insert a reference to the implicit superconstructor. |
| 494 InterfaceType superclass = | 486 InterfaceType superclass = |
| 495 (constant.returnType as InterfaceType).superclass; | 487 (constant.returnType as InterfaceType).superclass; |
| 496 if (superclass != null && !superclass.isObject) { | 488 if (superclass != null && !superclass.isObject) { |
| 497 ConstructorElement unnamedConstructor = ConstantEvaluationEngine | 489 ConstructorElement unnamedConstructor = |
| 498 ._getConstructorBase(superclass.element.unnamedConstructor); | 490 _getConstructorBase(superclass.element.unnamedConstructor); |
| 499 if (unnamedConstructor != null) { | 491 if (unnamedConstructor != null) { |
| 500 callback(unnamedConstructor); | 492 callback(unnamedConstructor); |
| 501 } | 493 } |
| 502 } | 494 } |
| 503 } | 495 } |
| 504 for (FieldElement field in constant.enclosingElement.fields) { | 496 for (FieldElement field in constant.enclosingElement.fields) { |
| 505 // Note: non-static const isn't allowed but we handle it anyway so | 497 // Note: non-static const isn't allowed but we handle it anyway so |
| 506 // that we won't be confused by incorrect code. | 498 // that we won't be confused by incorrect code. |
| 507 if ((field.isFinal || field.isConst) && | 499 if ((field.isFinal || field.isConst) && |
| 508 !field.isStatic && | 500 !field.isStatic && |
| (...skipping 20 matching lines...) Expand all Loading... |
| 529 } else { | 521 } else { |
| 530 // This could happen in the event of invalid code. The error will be | 522 // This could happen in the event of invalid code. The error will be |
| 531 // reported at constant evaluation time. | 523 // reported at constant evaluation time. |
| 532 } | 524 } |
| 533 if (constNode.arguments != null) { | 525 if (constNode.arguments != null) { |
| 534 constNode.arguments.accept(referenceFinder); | 526 constNode.arguments.accept(referenceFinder); |
| 535 } | 527 } |
| 536 } else if (constant is VariableElement) { | 528 } else if (constant is VariableElement) { |
| 537 // constant is a VariableElement but not a VariableElementImpl. This can | 529 // constant is a VariableElement but not a VariableElementImpl. This can |
| 538 // happen sometimes in the case of invalid user code (for example, a | 530 // happen sometimes in the case of invalid user code (for example, a |
| 539 // constant expression that refers to a nonstatic field inside a generic | 531 // constant expression that refers to a non-static field inside a generic |
| 540 // class will wind up referring to a FieldMember). So just don't bother | 532 // class will wind up referring to a FieldMember). So just don't bother |
| 541 // computing any dependencies. | 533 // computing any dependencies. |
| 542 } else { | 534 } else { |
| 543 // Should not happen. | 535 // Should not happen. |
| 544 assert(false); | 536 assert(false); |
| 545 AnalysisEngine.instance.logger.logError( | 537 AnalysisEngine.instance.logger.logError( |
| 546 "Constant value computer trying to compute the value of a node of type
${constant.runtimeType}"); | 538 "Constant value computer trying to compute the value of a node of type
${constant.runtimeType}"); |
| 547 } | 539 } |
| 548 } | 540 } |
| 549 | 541 |
| (...skipping 4876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5426 return BoolState.from(_element == rightElement); | 5418 return BoolState.from(_element == rightElement); |
| 5427 } else if (rightOperand is DynamicState) { | 5419 } else if (rightOperand is DynamicState) { |
| 5428 return BoolState.UNKNOWN_VALUE; | 5420 return BoolState.UNKNOWN_VALUE; |
| 5429 } | 5421 } |
| 5430 return BoolState.FALSE_STATE; | 5422 return BoolState.FALSE_STATE; |
| 5431 } | 5423 } |
| 5432 | 5424 |
| 5433 @override | 5425 @override |
| 5434 String toString() => _element == null ? "-unknown-" : _element.name; | 5426 String toString() => _element == null ? "-unknown-" : _element.name; |
| 5435 } | 5427 } |
| OLD | NEW |