| 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library engine.constant; | 8 library engine.constant; |
| 9 | 9 |
| 10 import 'dart:collection'; | 10 import 'dart:collection'; |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 RecordingErrorListener errorListener = new RecordingErrorListener(); | 322 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 323 ErrorReporter errorReporter = | 323 ErrorReporter errorReporter = |
| 324 new ErrorReporter(errorListener, constant.source); | 324 new ErrorReporter(errorListener, constant.source); |
| 325 DartObjectImpl dartObject = | 325 DartObjectImpl dartObject = |
| 326 defaultValue.accept(new ConstantVisitor(this, errorReporter)); | 326 defaultValue.accept(new ConstantVisitor(this, errorReporter)); |
| 327 (constant as ParameterElementImpl).evaluationResult = | 327 (constant as ParameterElementImpl).evaluationResult = |
| 328 new EvaluationResultImpl(dartObject, errorListener.errors); | 328 new EvaluationResultImpl(dartObject, errorListener.errors); |
| 329 } | 329 } |
| 330 } | 330 } |
| 331 } else if (constant is VariableElement) { | 331 } else if (constant is VariableElement) { |
| 332 RecordingErrorListener errorListener = new RecordingErrorListener(); | 332 Expression constantInitializer = |
| 333 ErrorReporter errorReporter = | 333 (constant as PotentiallyConstVariableElement).constantInitializer; |
| 334 new ErrorReporter(errorListener, constant.source); | 334 if (constantInitializer != null) { |
| 335 DartObjectImpl dartObject = | 335 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 336 (constant as PotentiallyConstVariableElement).constantInitializer | 336 ErrorReporter errorReporter = |
| 337 .accept(new ConstantVisitor(this, errorReporter)); | 337 new ErrorReporter(errorListener, constant.source); |
| 338 // Only check the type for truly const declarations (don't check final | 338 DartObjectImpl dartObject = constantInitializer |
| 339 // fields with initializers, since their types may be generic. The type | 339 .accept(new ConstantVisitor(this, errorReporter)); |
| 340 // of the final field will be checked later, when the constructor is | 340 // Only check the type for truly const declarations (don't check final |
| 341 // invoked). | 341 // fields with initializers, since their types may be generic. The type |
| 342 if (dartObject != null && constant.isConst) { | 342 // of the final field will be checked later, when the constructor is |
| 343 if (!runtimeTypeMatch(dartObject, constant.type)) { | 343 // invoked). |
| 344 errorReporter.reportErrorForElement( | 344 if (dartObject != null && constant.isConst) { |
| 345 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, constant, | 345 if (!runtimeTypeMatch(dartObject, constant.type)) { |
| 346 [dartObject.type, constant.type]); | 346 errorReporter.reportErrorForElement( |
| 347 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, |
| 348 constant, [dartObject.type, constant.type]); |
| 349 } |
| 347 } | 350 } |
| 351 (constant as VariableElementImpl).evaluationResult = |
| 352 new EvaluationResultImpl(dartObject, errorListener.errors); |
| 348 } | 353 } |
| 349 (constant as VariableElementImpl).evaluationResult = | |
| 350 new EvaluationResultImpl(dartObject, errorListener.errors); | |
| 351 } else if (constant is ConstructorElement) { | 354 } else if (constant is ConstructorElement) { |
| 352 // No evaluation needs to be done; constructor declarations are only in | 355 if (constant.isConst) { |
| 353 // the dependency graph to ensure that any constants referred to in | 356 // No evaluation needs to be done; constructor declarations are only in |
| 354 // initializer lists and parameter defaults are evaluated before | 357 // the dependency graph to ensure that any constants referred to in |
| 355 // invocations of the constructor. However we do need to annotate the | 358 // initializer lists and parameter defaults are evaluated before |
| 356 // element as being free of constant evaluation cycles so that later code | 359 // invocations of the constructor. However we do need to annotate the |
| 357 // will know that it is safe to evaluate. | 360 // element as being free of constant evaluation cycles so that later |
| 358 (constant as ConstructorElementImpl).isCycleFree = true; | 361 // code will know that it is safe to evaluate. |
| 362 (constant as ConstructorElementImpl).isCycleFree = true; |
| 363 } |
| 359 } else if (constant is ConstantEvaluationTarget_Annotation) { | 364 } else if (constant is ConstantEvaluationTarget_Annotation) { |
| 360 Annotation constNode = constant.annotation; | 365 Annotation constNode = constant.annotation; |
| 361 ElementAnnotationImpl elementAnnotation = constNode.elementAnnotation; | 366 ElementAnnotationImpl elementAnnotation = constNode.elementAnnotation; |
| 362 // elementAnnotation is null if the annotation couldn't be resolved, in | 367 // elementAnnotation is null if the annotation couldn't be resolved, in |
| 363 // which case we skip it. | 368 // which case we skip it. |
| 364 if (elementAnnotation != null) { | 369 if (elementAnnotation != null) { |
| 365 Element element = elementAnnotation.element; | 370 Element element = elementAnnotation.element; |
| 366 if (element is PropertyAccessorElement && | 371 if (element is PropertyAccessorElement && |
| 367 element.variable is VariableElementImpl) { | 372 element.variable is VariableElementImpl) { |
| 368 // The annotation is a reference to a compile-time constant variable. | 373 // The annotation is a reference to a compile-time constant variable. |
| 369 // Just copy the evaluation result. | 374 // Just copy the evaluation result. |
| 370 VariableElementImpl variableElement = | 375 VariableElementImpl variableElement = |
| 371 element.variable as VariableElementImpl; | 376 element.variable as VariableElementImpl; |
| 372 elementAnnotation.evaluationResult = variableElement.evaluationResult; | 377 if (variableElement.evaluationResult != null) { |
| 378 elementAnnotation.evaluationResult = |
| 379 variableElement.evaluationResult; |
| 380 } else { |
| 381 // This could happen in the event that the annotation refers to a |
| 382 // non-constant. The error is detected elsewhere, so just silently |
| 383 // ignore it here. |
| 384 elementAnnotation.evaluationResult = new EvaluationResultImpl(null); |
| 385 } |
| 373 } else if (element is ConstructorElementImpl && | 386 } else if (element is ConstructorElementImpl && |
| 374 element.isConst && | 387 element.isConst && |
| 375 constNode.arguments != null) { | 388 constNode.arguments != null) { |
| 376 RecordingErrorListener errorListener = new RecordingErrorListener(); | 389 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 377 CompilationUnit sourceCompilationUnit = | 390 CompilationUnit sourceCompilationUnit = |
| 378 constNode.getAncestor((node) => node is CompilationUnit); | 391 constNode.getAncestor((node) => node is CompilationUnit); |
| 379 ErrorReporter errorReporter = new ErrorReporter( | 392 ErrorReporter errorReporter = new ErrorReporter( |
| 380 errorListener, sourceCompilationUnit.element.source); | 393 errorListener, sourceCompilationUnit.element.source); |
| 381 ConstantVisitor constantVisitor = | 394 ConstantVisitor constantVisitor = |
| 382 new ConstantVisitor(this, errorReporter); | 395 new ConstantVisitor(this, errorReporter); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 398 AnalysisEngine.instance.logger.logError( | 411 AnalysisEngine.instance.logger.logError( |
| 399 "Constant value computer trying to compute the value of a node of type
${constant.runtimeType}"); | 412 "Constant value computer trying to compute the value of a node of type
${constant.runtimeType}"); |
| 400 return; | 413 return; |
| 401 } | 414 } |
| 402 } | 415 } |
| 403 | 416 |
| 404 /** | 417 /** |
| 405 * Determine which constant elements need to have their values computed | 418 * Determine which constant elements need to have their values computed |
| 406 * prior to computing the value of [constant], and report them using | 419 * prior to computing the value of [constant], and report them using |
| 407 * [callback]. | 420 * [callback]. |
| 421 * |
| 422 * Note that it's possible (in erroneous code) for a constant to depend on a |
| 423 * non-constant. When this happens, we report the dependency anyhow so that |
| 424 * if the non-constant changes to a constant, we will know to recompute the |
| 425 * thing that depends on it. [computeDependencies] and |
| 426 * [computeConstantValue] are responsible for ignoring the request if they |
| 427 * are asked to act on a non-constant target. |
| 408 */ | 428 */ |
| 409 void computeDependencies( | 429 void computeDependencies( |
| 410 ConstantEvaluationTarget constant, ReferenceFinderCallback callback) { | 430 ConstantEvaluationTarget constant, ReferenceFinderCallback callback) { |
| 411 ReferenceFinder referenceFinder = new ReferenceFinder(callback); | 431 ReferenceFinder referenceFinder = new ReferenceFinder(callback); |
| 412 if (constant is ParameterElement) { | 432 if (constant is ParameterElement) { |
| 413 if (constant.initializer != null) { | 433 if (constant.initializer != null) { |
| 414 Expression defaultValue = | 434 Expression defaultValue = |
| 415 (constant as ConstVariableElement).constantInitializer; | 435 (constant as ConstVariableElement).constantInitializer; |
| 416 if (defaultValue != null) { | 436 if (defaultValue != null) { |
| 417 defaultValue.accept(referenceFinder); | 437 defaultValue.accept(referenceFinder); |
| 418 } | 438 } |
| 419 } | 439 } |
| 420 } else if (constant is PotentiallyConstVariableElement) { | 440 } else if (constant is PotentiallyConstVariableElement) { |
| 421 Expression initializer = constant.constantInitializer; | 441 Expression initializer = constant.constantInitializer; |
| 422 if (initializer != null) { | 442 if (initializer != null) { |
| 423 initializer.accept(referenceFinder); | 443 initializer.accept(referenceFinder); |
| 424 } | 444 } |
| 425 } else if (constant is ConstructorElementImpl) { | 445 } else if (constant is ConstructorElementImpl) { |
| 426 constant.isCycleFree = false; | 446 if (constant.isConst) { |
| 427 ConstructorElement redirectedConstructor = | 447 constant.isCycleFree = false; |
| 428 getConstRedirectedConstructor(constant); | 448 ConstructorElement redirectedConstructor = |
| 429 if (redirectedConstructor != null) { | 449 getConstRedirectedConstructor(constant); |
| 430 ConstructorElement redirectedConstructorBase = | 450 if (redirectedConstructor != null) { |
| 431 ConstantEvaluationEngine._getConstructorBase(redirectedConstructor); | 451 ConstructorElement redirectedConstructorBase = |
| 432 callback(redirectedConstructorBase); | 452 ConstantEvaluationEngine |
| 433 return; | 453 ._getConstructorBase(redirectedConstructor); |
| 434 } else if (constant.isFactory) { | 454 callback(redirectedConstructorBase); |
| 435 // Factory constructor, but getConstRedirectedConstructor returned | 455 return; |
| 436 // null. This can happen if we're visiting one of the special external | 456 } else if (constant.isFactory) { |
| 437 // const factory constructors in the SDK, or if the code contains | 457 // Factory constructor, but getConstRedirectedConstructor returned |
| 438 // errors (such as delegating to a non-const constructor, or delegating | 458 // null. This can happen if we're visiting one of the special externa
l |
| 439 // to a constructor that can't be resolved). In any of these cases, | 459 // const factory constructors in the SDK, or if the code contains |
| 440 // we'll evaluate calls to this constructor without having to refer to | 460 // errors (such as delegating to a non-const constructor, or delegatin
g |
| 441 // any other constants. So we don't need to report any dependencies. | 461 // to a constructor that can't be resolved). In any of these cases, |
| 442 return; | 462 // we'll evaluate calls to this constructor without having to refer to |
| 443 } | 463 // any other constants. So we don't need to report any dependencies. |
| 444 bool superInvocationFound = false; | 464 return; |
| 445 List<ConstructorInitializer> initializers = constant.constantInitializers; | |
| 446 for (ConstructorInitializer initializer in initializers) { | |
| 447 if (initializer is SuperConstructorInvocation) { | |
| 448 superInvocationFound = true; | |
| 449 } | 465 } |
| 450 initializer.accept(referenceFinder); | 466 bool superInvocationFound = false; |
| 451 } | 467 List<ConstructorInitializer> initializers = |
| 452 if (!superInvocationFound) { | 468 constant.constantInitializers; |
| 453 // No explicit superconstructor invocation found, so we need to | 469 for (ConstructorInitializer initializer in initializers) { |
| 454 // manually insert a reference to the implicit superconstructor. | 470 if (initializer is SuperConstructorInvocation) { |
| 455 InterfaceType superclass = | 471 superInvocationFound = true; |
| 456 (constant.returnType as InterfaceType).superclass; | 472 } |
| 457 if (superclass != null && !superclass.isObject) { | 473 initializer.accept(referenceFinder); |
| 458 ConstructorElement unnamedConstructor = ConstantEvaluationEngine | 474 } |
| 459 ._getConstructorBase(superclass.element.unnamedConstructor); | 475 if (!superInvocationFound) { |
| 460 if (unnamedConstructor != null && unnamedConstructor.isConst) { | 476 // No explicit superconstructor invocation found, so we need to |
| 461 callback(unnamedConstructor); | 477 // manually insert a reference to the implicit superconstructor. |
| 478 InterfaceType superclass = |
| 479 (constant.returnType as InterfaceType).superclass; |
| 480 if (superclass != null && !superclass.isObject) { |
| 481 ConstructorElement unnamedConstructor = ConstantEvaluationEngine |
| 482 ._getConstructorBase(superclass.element.unnamedConstructor); |
| 483 if (unnamedConstructor != null) { |
| 484 callback(unnamedConstructor); |
| 485 } |
| 462 } | 486 } |
| 463 } | 487 } |
| 464 } | 488 for (FieldElement field in constant.enclosingElement.fields) { |
| 465 for (FieldElement field in constant.enclosingElement.fields) { | 489 // Note: non-static const isn't allowed but we handle it anyway so |
| 466 // Note: non-static const isn't allowed but we handle it anyway so that | 490 // that we won't be confused by incorrect code. |
| 467 // we won't be confused by incorrect code. | 491 if ((field.isFinal || field.isConst) && |
| 468 if ((field.isFinal || field.isConst) && | 492 !field.isStatic && |
| 469 !field.isStatic && | 493 field.initializer != null) { |
| 470 field.initializer != null) { | 494 callback(field); |
| 471 callback(field); | 495 } |
| 472 } | 496 } |
| 473 } | 497 for (ParameterElement parameterElement in constant.parameters) { |
| 474 for (ParameterElement parameterElement in constant.parameters) { | 498 callback(parameterElement); |
| 475 callback(parameterElement); | 499 } |
| 476 } | 500 } |
| 477 } else if (constant is ConstantEvaluationTarget_Annotation) { | 501 } else if (constant is ConstantEvaluationTarget_Annotation) { |
| 478 Annotation constNode = constant.annotation; | 502 Annotation constNode = constant.annotation; |
| 479 ElementAnnotationImpl elementAnnotation = constNode.elementAnnotation; | 503 ElementAnnotationImpl elementAnnotation = constNode.elementAnnotation; |
| 480 // elementAnnotation is null if the annotation couldn't be resolved, in | 504 // elementAnnotation is null if the annotation couldn't be resolved, in |
| 481 // which case we skip it. | 505 // which case we skip it. |
| 482 if (elementAnnotation != null) { | 506 if (elementAnnotation != null) { |
| 483 Element element = elementAnnotation.element; | 507 Element element = elementAnnotation.element; |
| 484 if (element is PropertyAccessorElement && | 508 if (element is PropertyAccessorElement && |
| 485 element.variable is VariableElementImpl) { | 509 element.variable is VariableElementImpl) { |
| 486 // The annotation is a reference to a compile-time constant variable, | 510 // The annotation is a reference to a compile-time constant variable, |
| 487 // so it depends on the variable. | 511 // so it depends on the variable. |
| 488 callback(element.variable); | 512 callback(element.variable); |
| 489 } else if (element is ConstructorElementImpl && element.isConst) { | 513 } else if (element is ConstructorElementImpl) { |
| 490 // The annotation is a constructor invocation, so it depends on the | 514 // The annotation is a constructor invocation, so it depends on the |
| 491 // constructor. | 515 // constructor. |
| 492 callback(element); | 516 callback(element); |
| 493 } else { | 517 } else { |
| 494 // This could happen in the event of invalid code. The error will be | 518 // This could happen in the event of invalid code. The error will be |
| 495 // reported at constant evaluation time. | 519 // reported at constant evaluation time. |
| 496 } | 520 } |
| 497 } | 521 } |
| 498 if (constNode.arguments != null) { | 522 if (constNode.arguments != null) { |
| 499 constNode.arguments.accept(referenceFinder); | 523 constNode.arguments.accept(referenceFinder); |
| (...skipping 4472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4972 } | 4996 } |
| 4973 return super.visitInstanceCreationExpression(node); | 4997 return super.visitInstanceCreationExpression(node); |
| 4974 } | 4998 } |
| 4975 | 4999 |
| 4976 @override | 5000 @override |
| 4977 Object visitRedirectingConstructorInvocation( | 5001 Object visitRedirectingConstructorInvocation( |
| 4978 RedirectingConstructorInvocation node) { | 5002 RedirectingConstructorInvocation node) { |
| 4979 super.visitRedirectingConstructorInvocation(node); | 5003 super.visitRedirectingConstructorInvocation(node); |
| 4980 ConstructorElement target = | 5004 ConstructorElement target = |
| 4981 ConstantEvaluationEngine._getConstructorBase(node.staticElement); | 5005 ConstantEvaluationEngine._getConstructorBase(node.staticElement); |
| 4982 if (target != null && target.isConst) { | 5006 if (target != null) { |
| 4983 _callback(target); | 5007 _callback(target); |
| 4984 } | 5008 } |
| 4985 return null; | 5009 return null; |
| 4986 } | 5010 } |
| 4987 | 5011 |
| 4988 @override | 5012 @override |
| 4989 Object visitSimpleIdentifier(SimpleIdentifier node) { | 5013 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 4990 Element element = node.staticElement; | 5014 Element element = node.staticElement; |
| 4991 if (element is PropertyAccessorElement) { | 5015 if (element is PropertyAccessorElement) { |
| 4992 element = (element as PropertyAccessorElement).variable; | 5016 element = (element as PropertyAccessorElement).variable; |
| 4993 } | 5017 } |
| 4994 if (element is VariableElement) { | 5018 if (element is VariableElement) { |
| 4995 if (element.isConst) { | 5019 _callback(element); |
| 4996 _callback(element); | |
| 4997 } | |
| 4998 } | 5020 } |
| 4999 return null; | 5021 return null; |
| 5000 } | 5022 } |
| 5001 | 5023 |
| 5002 @override | 5024 @override |
| 5003 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 5025 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 5004 super.visitSuperConstructorInvocation(node); | 5026 super.visitSuperConstructorInvocation(node); |
| 5005 ConstructorElement constructor = | 5027 ConstructorElement constructor = |
| 5006 ConstantEvaluationEngine._getConstructorBase(node.staticElement); | 5028 ConstantEvaluationEngine._getConstructorBase(node.staticElement); |
| 5007 if (constructor != null && constructor.isConst) { | 5029 if (constructor != null) { |
| 5008 _callback(constructor); | 5030 _callback(constructor); |
| 5009 } | 5031 } |
| 5010 return null; | 5032 return null; |
| 5011 } | 5033 } |
| 5012 } | 5034 } |
| 5013 | 5035 |
| 5014 /** | 5036 /** |
| 5015 * The state of an object representing a string. | 5037 * The state of an object representing a string. |
| 5016 */ | 5038 */ |
| 5017 class StringState extends InstanceState { | 5039 class StringState extends InstanceState { |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5220 return BoolState.from(_element == rightElement); | 5242 return BoolState.from(_element == rightElement); |
| 5221 } else if (rightOperand is DynamicState) { | 5243 } else if (rightOperand is DynamicState) { |
| 5222 return BoolState.UNKNOWN_VALUE; | 5244 return BoolState.UNKNOWN_VALUE; |
| 5223 } | 5245 } |
| 5224 return BoolState.FALSE_STATE; | 5246 return BoolState.FALSE_STATE; |
| 5225 } | 5247 } |
| 5226 | 5248 |
| 5227 @override | 5249 @override |
| 5228 String toString() => _element == null ? "-unknown-" : _element.name; | 5250 String toString() => _element == null ? "-unknown-" : _element.name; |
| 5229 } | 5251 } |
| OLD | NEW |