| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 package com.google.dart.compiler.resolver; | 5 package com.google.dart.compiler.resolver; |
| 6 | 6 |
| 7 import com.google.common.collect.Maps; | 7 import com.google.common.collect.Maps; |
| 8 import com.google.common.collect.Sets; | 8 import com.google.common.collect.Sets; |
| 9 import com.google.dart.compiler.DartCompilationError; | 9 import com.google.dart.compiler.DartCompilationError; |
| 10 import com.google.dart.compiler.DartCompilationPhase; | 10 import com.google.dart.compiler.DartCompilationPhase; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 * each expression matches all the rules for a compile-time constant. Emits a | 61 * each expression matches all the rules for a compile-time constant. Emits a |
| 62 * resolution error if not. | 62 * resolution error if not. |
| 63 * | 63 * |
| 64 * This script doesn't just resolve expressions, it also sets types to the | 64 * This script doesn't just resolve expressions, it also sets types to the |
| 65 * extent needed to validate compile-time constant expressions (boolean, int, | 65 * extent needed to validate compile-time constant expressions (boolean, int, |
| 66 * double, and string types might be set) | 66 * double, and string types might be set) |
| 67 */ | 67 */ |
| 68 public class CompileTimeConstantAnalyzer { | 68 public class CompileTimeConstantAnalyzer { |
| 69 | 69 |
| 70 private class ExpressionVisitor extends ASTVisitor<Void> { | 70 private class ExpressionVisitor extends ASTVisitor<Void> { |
| 71 private ExpressionVisitor() { | 71 private final boolean shouldBeStatic; |
| 72 |
| 73 private ExpressionVisitor(boolean shouldBeStatic) { |
| 74 this.shouldBeStatic = shouldBeStatic; |
| 72 } | 75 } |
| 73 | 76 |
| 74 private boolean checkBoolean(DartNode x, Type type) { | 77 private boolean checkBoolean(DartNode x, Type type) { |
| 75 // Spec 0.11 allows using "null" literal in place of bool. | 78 // Spec 0.11 allows using "null" literal in place of bool. |
| 76 if (x instanceof DartNullLiteral) { | 79 if (x instanceof DartNullLiteral) { |
| 77 return true; | 80 return true; |
| 78 } | 81 } |
| 79 // check actual type | 82 // check actual type |
| 80 if (!type.equals(boolType)) { | 83 if (!type.equals(boolType)) { |
| 81 context.onError(new DartCompilationError(x, | 84 context.onError(new DartCompilationError(x, |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 @Override | 363 @Override |
| 361 public Void visitIdentifier(DartIdentifier x) { | 364 public Void visitIdentifier(DartIdentifier x) { |
| 362 x.visitChildren(this); | 365 x.visitChildren(this); |
| 363 | 366 |
| 364 if (x.getParent() instanceof DartDeclaration<?> | 367 if (x.getParent() instanceof DartDeclaration<?> |
| 365 && ((DartDeclaration<?>) x.getParent()).getName() == x) { | 368 && ((DartDeclaration<?>) x.getParent()).getName() == x) { |
| 366 return null; | 369 return null; |
| 367 } | 370 } |
| 368 | 371 |
| 369 Element element = x.getElement(); | 372 Element element = x.getElement(); |
| 373 boolean elementIsStatic = element != null |
| 374 && (element.getModifiers().isStatic() || Elements.isTopLevel(element))
; |
| 370 switch (ElementKind.of(element)) { | 375 switch (ElementKind.of(element)) { |
| 371 case CLASS: | 376 case CLASS: |
| 372 case PARAMETER: | 377 case PARAMETER: |
| 373 case LIBRARY_PREFIX: | 378 case LIBRARY_PREFIX: |
| 374 break; | 379 break; |
| 375 | 380 |
| 376 case FIELD: | 381 case FIELD: |
| 377 FieldElement fieldElement = (FieldElement) element; | 382 FieldElement fieldElement = (FieldElement) element; |
| 378 | 383 |
| 384 if (shouldBeStatic && !elementIsStatic) { |
| 385 context.onError(new DartCompilationError(x, ResolverErrorCode.NOT_A_
STATIC_FIELD, |
| 386 fieldElement.getName())); |
| 387 } |
| 388 |
| 379 // Check for circular references. | 389 // Check for circular references. |
| 380 if (element != null && visitedElements.contains(element)) { | 390 if (element != null && visitedElements.contains(element)) { |
| 381 context.onError(new DartCompilationError(x, ResolverErrorCode.CIRCUL
AR_REFERENCE)); | 391 context.onError(new DartCompilationError(x, ResolverErrorCode.CIRCUL
AR_REFERENCE)); |
| 382 rememberInferredType(x, getMostSpecificType(x)); | 392 rememberInferredType(x, getMostSpecificType(x)); |
| 383 return null; | 393 return null; |
| 384 } | 394 } |
| 385 visitedElements.add(element); | 395 visitedElements.add(element); |
| 386 | 396 |
| 387 // Should be declared as constant. | 397 // Should be declared as constant. |
| 388 if (!element.getModifiers().isConstant()) { | 398 if (!element.getModifiers().isConstant()) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 410 rememberInferredType(x, inferredType); | 420 rememberInferredType(x, inferredType); |
| 411 break; | 421 break; |
| 412 | 422 |
| 413 case VARIABLE: | 423 case VARIABLE: |
| 414 if (!element.getModifiers().isConstant()) { | 424 if (!element.getModifiers().isConstant()) { |
| 415 expectedConstant(x); | 425 expectedConstant(x); |
| 416 } | 426 } |
| 417 return null; | 427 return null; |
| 418 | 428 |
| 419 case METHOD: | 429 case METHOD: |
| 420 if (!element.getModifiers().isStatic() && !Elements.isTopLevel(element
)) { | 430 if (!elementIsStatic) { |
| 421 expectedConstant(x); | 431 expectedConstant(x); |
| 422 } | 432 } |
| 423 return null; | 433 return null; |
| 424 | 434 |
| 425 case NONE: | 435 case NONE: |
| 426 default: | 436 default: |
| 427 expectedConstant(x); | 437 expectedConstant(x); |
| 428 return null; | 438 return null; |
| 429 } | 439 } |
| 430 return null; | 440 return null; |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 } | 631 } |
| 622 return null; | 632 return null; |
| 623 } | 633 } |
| 624 return super.visitArrayLiteral(node); | 634 return super.visitArrayLiteral(node); |
| 625 } | 635 } |
| 626 | 636 |
| 627 @Override | 637 @Override |
| 628 public Void visitField(DartField node) { | 638 public Void visitField(DartField node) { |
| 629 if (node.getParent() != null) { | 639 if (node.getParent() != null) { |
| 630 if (node.getModifiers().isConstant()) { | 640 if (node.getModifiers().isConstant()) { |
| 631 Type type = checkConstantExpression(node.getValue()); | 641 Type type = checkConstantExpression(node.getValue(), node.getModifiers
().isStatic()); |
| 632 if (node.getElement().getType().equals(dynamicType)) { | 642 if (node.getElement().getType().equals(dynamicType)) { |
| 633 node.getElement().setConstantType(type); | 643 node.getElement().setConstantType(type); |
| 634 } | 644 } |
| 635 return null; | 645 return null; |
| 636 } | 646 } |
| 637 } | 647 } |
| 638 return super.visitField(node); | 648 return super.visitField(node); |
| 639 } | 649 } |
| 640 | 650 |
| 641 @Override | 651 @Override |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 this.context = context; | 790 this.context = context; |
| 781 this.boolType = typeProvider.getBoolType(); | 791 this.boolType = typeProvider.getBoolType(); |
| 782 this.doubleType = typeProvider.getDoubleType(); | 792 this.doubleType = typeProvider.getDoubleType(); |
| 783 this.intType = typeProvider.getIntType(); | 793 this.intType = typeProvider.getIntType(); |
| 784 this.numType = typeProvider.getNumType(); | 794 this.numType = typeProvider.getNumType(); |
| 785 this.stringType = typeProvider.getStringType(); | 795 this.stringType = typeProvider.getStringType(); |
| 786 this.dynamicType = typeProvider.getDynamicType(); | 796 this.dynamicType = typeProvider.getDynamicType(); |
| 787 } | 797 } |
| 788 | 798 |
| 789 private Type checkConstantExpression(DartExpression expression) { | 799 private Type checkConstantExpression(DartExpression expression) { |
| 800 return checkConstantExpression(expression, false); |
| 801 } |
| 802 |
| 803 private Type checkConstantExpression(DartExpression expression, boolean should
BeStatic) { |
| 790 if (expression != null) { | 804 if (expression != null) { |
| 791 ExpressionVisitor visitor = new ExpressionVisitor(); | 805 ExpressionVisitor visitor = new ExpressionVisitor(shouldBeStatic); |
| 792 expression.accept(visitor); | 806 expression.accept(visitor); |
| 793 return visitor.getMostSpecificType(expression); | 807 return visitor.getMostSpecificType(expression); |
| 794 } | 808 } |
| 795 return null; | 809 return null; |
| 796 } | 810 } |
| 797 | 811 |
| 798 public void exec(DartUnit unit) { | 812 public void exec(DartUnit unit) { |
| 799 unit.accept(new FindCompileTimeConstantExpressionsVisitor()); | 813 unit.accept(new FindCompileTimeConstantExpressionsVisitor()); |
| 800 } | 814 } |
| 801 } | 815 } |
| OLD | NEW |