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

Unified Diff: packages/analyzer/test/generated/all_the_rest_test.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « packages/analyzer/test/file_system/test_all.dart ('k') | packages/analyzer/test/generated/ast_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: packages/analyzer/test/generated/all_the_rest_test.dart
diff --git a/packages/analyzer/test/generated/all_the_rest_test.dart b/packages/analyzer/test/generated/all_the_rest_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..cabe5d7d50f1bd90c5cd8693df4d6d0febed1e62
--- /dev/null
+++ b/packages/analyzer/test/generated/all_the_rest_test.dart
@@ -0,0 +1,9372 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library engine.all_the_rest_test;
+
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/html.dart' as ht;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/testing/html_factory.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:path/path.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'engine_test.dart';
+import 'parser_test.dart';
+import 'resolver_test.dart';
+import 'test_support.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(ConstantEvaluatorTest);
+ runReflectiveTests(ConstantFinderTest);
+ runReflectiveTests(ConstantValueComputerTest);
+ runReflectiveTests(ConstantVisitorTest);
+ runReflectiveTests(ContentCacheTest);
+ runReflectiveTests(CustomUriResolverTest);
+ runReflectiveTests(DartObjectImplTest);
+ runReflectiveTests(DartUriResolverTest);
+ runReflectiveTests(DeclaredVariablesTest);
+ runReflectiveTests(DirectoryBasedDartSdkTest);
+ runReflectiveTests(DirectoryBasedSourceContainerTest);
+ runReflectiveTests(ElementBuilderTest);
+ runReflectiveTests(ElementLocatorTest);
+ runReflectiveTests(EnumMemberBuilderTest);
+ runReflectiveTests(ErrorReporterTest);
+ runReflectiveTests(ErrorSeverityTest);
+ runReflectiveTests(ExitDetectorTest);
+ runReflectiveTests(ExitDetectorTest2);
+ runReflectiveTests(FileBasedSourceTest);
+ runReflectiveTests(FileUriResolverTest);
+ if (!AnalysisEngine.instance.useTaskModel) {
+ runReflectiveTests(HtmlParserTest);
+ runReflectiveTests(HtmlTagInfoBuilderTest);
+ runReflectiveTests(HtmlUnitBuilderTest);
+ runReflectiveTests(HtmlWarningCodeTest);
+ }
+ runReflectiveTests(ReferenceFinderTest);
+ runReflectiveTests(SDKLibrariesReaderTest);
+ runReflectiveTests(ToSourceVisitorTest);
+ runReflectiveTests(UriKindTest);
+ runReflectiveTests(StringScannerTest);
+}
+
+abstract class AbstractScannerTest {
+ ht.AbstractScanner newScanner(String input);
+
+ void test_tokenize_attribute() {
+ _tokenize("<html bob=\"one two\">", <Object>[
+ ht.TokenType.LT,
+ "html",
+ "bob",
+ ht.TokenType.EQ,
+ "\"one two\"",
+ ht.TokenType.GT
+ ]);
+ }
+
+ void test_tokenize_comment() {
+ _tokenize("<!-- foo -->", <Object>["<!-- foo -->"]);
+ }
+
+ void test_tokenize_comment_incomplete() {
+ _tokenize("<!-- foo", <Object>["<!-- foo"]);
+ }
+
+ void test_tokenize_comment_with_gt() {
+ _tokenize("<!-- foo > -> -->", <Object>["<!-- foo > -> -->"]);
+ }
+
+ void test_tokenize_declaration() {
+ _tokenize("<! foo ><html>",
+ <Object>["<! foo >", ht.TokenType.LT, "html", ht.TokenType.GT]);
+ }
+
+ void test_tokenize_declaration_malformed() {
+ _tokenize("<! foo /><html>",
+ <Object>["<! foo />", ht.TokenType.LT, "html", ht.TokenType.GT]);
+ }
+
+ void test_tokenize_directive_incomplete() {
+ _tokenize2("<? \nfoo", <Object>["<? \nfoo"], <int>[0, 4]);
+ }
+
+ void test_tokenize_directive_xml() {
+ _tokenize("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>",
+ <Object>["<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"]);
+ }
+
+ void test_tokenize_directives_incomplete_with_newline() {
+ _tokenize2("<! \nfoo", <Object>["<! \nfoo"], <int>[0, 4]);
+ }
+
+ void test_tokenize_empty() {
+ _tokenize("", <Object>[]);
+ }
+
+ void test_tokenize_lt() {
+ _tokenize("<", <Object>[ht.TokenType.LT]);
+ }
+
+ void test_tokenize_script_embedded_tags() {
+ _tokenize("<script> <p></p></script>", <Object>[
+ ht.TokenType.LT,
+ "script",
+ ht.TokenType.GT,
+ " <p></p>",
+ ht.TokenType.LT_SLASH,
+ "script",
+ ht.TokenType.GT
+ ]);
+ }
+
+ void test_tokenize_script_embedded_tags2() {
+ _tokenize("<script> <p></p><</script>", <Object>[
+ ht.TokenType.LT,
+ "script",
+ ht.TokenType.GT,
+ " <p></p><",
+ ht.TokenType.LT_SLASH,
+ "script",
+ ht.TokenType.GT
+ ]);
+ }
+
+ void test_tokenize_script_embedded_tags3() {
+ _tokenize("<script> <p></p></</script>", <Object>[
+ ht.TokenType.LT,
+ "script",
+ ht.TokenType.GT,
+ " <p></p></",
+ ht.TokenType.LT_SLASH,
+ "script",
+ ht.TokenType.GT
+ ]);
+ }
+
+ void test_tokenize_script_partial() {
+ _tokenize("<script> <p> ",
+ <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> "]);
+ }
+
+ void test_tokenize_script_partial2() {
+ _tokenize("<script> <p> <",
+ <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> <"]);
+ }
+
+ void test_tokenize_script_partial3() {
+ _tokenize("<script> <p> </",
+ <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> </"]);
+ }
+
+ void test_tokenize_script_ref() {
+ _tokenize("<script source='some.dart'/> <p>", <Object>[
+ ht.TokenType.LT,
+ "script",
+ "source",
+ ht.TokenType.EQ,
+ "'some.dart'",
+ ht.TokenType.SLASH_GT,
+ " ",
+ ht.TokenType.LT,
+ "p",
+ ht.TokenType.GT
+ ]);
+ }
+
+ void test_tokenize_script_with_newline() {
+ _tokenize2("<script> <p>\n </script>", <Object>[
+ ht.TokenType.LT,
+ "script",
+ ht.TokenType.GT,
+ " <p>\n ",
+ ht.TokenType.LT_SLASH,
+ "script",
+ ht.TokenType.GT
+ ], <int>[
+ 0,
+ 13
+ ]);
+ }
+
+ void test_tokenize_spaces_and_newlines() {
+ ht.Token token = _tokenize2(
+ " < html \n bob = 'joe\n' >\n <\np > one \r\n two <!-- \rfoo --> </ p > </ html > ",
+ <Object>[
+ " ",
+ ht.TokenType.LT,
+ "html",
+ "bob",
+ ht.TokenType.EQ,
+ "'joe\n'",
+ ht.TokenType.GT,
+ "\n ",
+ ht.TokenType.LT,
+ "p",
+ ht.TokenType.GT,
+ " one \r\n two ",
+ "<!-- \rfoo -->",
+ " ",
+ ht.TokenType.LT_SLASH,
+ "p",
+ ht.TokenType.GT,
+ " ",
+ ht.TokenType.LT_SLASH,
+ "html",
+ ht.TokenType.GT,
+ " "
+ ],
+ <int>[
+ 0,
+ 9,
+ 21,
+ 25,
+ 28,
+ 38,
+ 49
+ ]);
+ token = token.next;
+ expect(token.offset, 1);
+ token = token.next;
+ expect(token.offset, 3);
+ token = token.next;
+ expect(token.offset, 10);
+ }
+
+ void test_tokenize_string() {
+ _tokenize("<p bob=\"foo\">", <Object>[
+ ht.TokenType.LT,
+ "p",
+ "bob",
+ ht.TokenType.EQ,
+ "\"foo\"",
+ ht.TokenType.GT
+ ]);
+ }
+
+ void test_tokenize_string_partial() {
+ _tokenize("<p bob=\"foo",
+ <Object>[ht.TokenType.LT, "p", "bob", ht.TokenType.EQ, "\"foo"]);
+ }
+
+ void test_tokenize_string_single_quote() {
+ _tokenize("<p bob='foo'>", <Object>[
+ ht.TokenType.LT,
+ "p",
+ "bob",
+ ht.TokenType.EQ,
+ "'foo'",
+ ht.TokenType.GT
+ ]);
+ }
+
+ void test_tokenize_string_single_quote_partial() {
+ _tokenize("<p bob='foo",
+ <Object>[ht.TokenType.LT, "p", "bob", ht.TokenType.EQ, "'foo"]);
+ }
+
+ void test_tokenize_tag_begin_end() {
+ _tokenize("<html></html>", <Object>[
+ ht.TokenType.LT,
+ "html",
+ ht.TokenType.GT,
+ ht.TokenType.LT_SLASH,
+ "html",
+ ht.TokenType.GT
+ ]);
+ }
+
+ void test_tokenize_tag_begin_only() {
+ ht.Token token =
+ _tokenize("<html>", <Object>[ht.TokenType.LT, "html", ht.TokenType.GT]);
+ token = token.next;
+ expect(token.offset, 1);
+ }
+
+ void test_tokenize_tag_incomplete_with_special_characters() {
+ _tokenize("<br-a_b", <Object>[ht.TokenType.LT, "br-a_b"]);
+ }
+
+ void test_tokenize_tag_self_contained() {
+ _tokenize("<br/>", <Object>[ht.TokenType.LT, "br", ht.TokenType.SLASH_GT]);
+ }
+
+ void test_tokenize_tags_wellformed() {
+ _tokenize("<html><p>one two</p></html>", <Object>[
+ ht.TokenType.LT,
+ "html",
+ ht.TokenType.GT,
+ ht.TokenType.LT,
+ "p",
+ ht.TokenType.GT,
+ "one two",
+ ht.TokenType.LT_SLASH,
+ "p",
+ ht.TokenType.GT,
+ ht.TokenType.LT_SLASH,
+ "html",
+ ht.TokenType.GT
+ ]);
+ }
+
+ /**
+ * Given an object representing an expected token, answer the expected token type.
+ *
+ * @param count the token count for error reporting
+ * @param expected the object representing an expected token
+ * @return the expected token type
+ */
+ ht.TokenType _getExpectedTokenType(int count, Object expected) {
+ if (expected is ht.TokenType) {
+ return expected;
+ }
+ if (expected is String) {
+ String lexeme = expected;
+ if (lexeme.startsWith("\"") || lexeme.startsWith("'")) {
+ return ht.TokenType.STRING;
+ }
+ if (lexeme.startsWith("<!--")) {
+ return ht.TokenType.COMMENT;
+ }
+ if (lexeme.startsWith("<!")) {
+ return ht.TokenType.DECLARATION;
+ }
+ if (lexeme.startsWith("<?")) {
+ return ht.TokenType.DIRECTIVE;
+ }
+ if (_isTag(lexeme)) {
+ return ht.TokenType.TAG;
+ }
+ return ht.TokenType.TEXT;
+ }
+ fail(
+ "Unknown expected token $count: ${expected != null ? expected.runtimeType : "null"}");
+ return null;
+ }
+
+ bool _isTag(String lexeme) {
+ if (lexeme.length == 0 || !Character.isLetter(lexeme.codeUnitAt(0))) {
+ return false;
+ }
+ for (int index = 1; index < lexeme.length; index++) {
+ int ch = lexeme.codeUnitAt(index);
+ if (!Character.isLetterOrDigit(ch) && ch != 0x2D && ch != 0x5F) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ ht.Token _tokenize(String input, List<Object> expectedTokens) =>
+ _tokenize2(input, expectedTokens, <int>[0]);
+ ht.Token _tokenize2(
+ String input, List<Object> expectedTokens, List<int> expectedLineStarts) {
+ ht.AbstractScanner scanner = newScanner(input);
+ scanner.passThroughElements = <String>["script"];
+ int count = 0;
+ ht.Token firstToken = scanner.tokenize();
+ ht.Token token = firstToken;
+ ht.Token previousToken = token.previous;
+ expect(previousToken.type == ht.TokenType.EOF, isTrue);
+ expect(previousToken.previous, same(previousToken));
+ expect(previousToken.offset, -1);
+ expect(previousToken.next, same(token));
+ expect(token.offset, 0);
+ while (token.type != ht.TokenType.EOF) {
+ if (count == expectedTokens.length) {
+ fail("too many parsed tokens");
+ }
+ Object expected = expectedTokens[count];
+ ht.TokenType expectedTokenType = _getExpectedTokenType(count, expected);
+ expect(token.type, same(expectedTokenType), reason: "token $count");
+ if (expectedTokenType.lexeme != null) {
+ expect(token.lexeme, expectedTokenType.lexeme, reason: "token $count");
+ } else {
+ expect(token.lexeme, expected, reason: "token $count");
+ }
+ count++;
+ previousToken = token;
+ token = token.next;
+ expect(token.previous, same(previousToken));
+ }
+ expect(token.next, same(token));
+ expect(token.offset, input.length);
+ if (count != expectedTokens.length) {
+ expect(false, isTrue, reason: "not enough parsed tokens");
+ }
+ List<int> lineStarts = scanner.lineStarts;
+ bool success = expectedLineStarts.length == lineStarts.length;
+ if (success) {
+ for (int i = 0; i < lineStarts.length; i++) {
+ if (expectedLineStarts[i] != lineStarts[i]) {
+ success = false;
+ break;
+ }
+ }
+ }
+ if (!success) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write("Expected line starts ");
+ for (int start in expectedLineStarts) {
+ buffer.write(start);
+ buffer.write(", ");
+ }
+ buffer.write(" but found ");
+ for (int start in lineStarts) {
+ buffer.write(start);
+ buffer.write(", ");
+ }
+ fail(buffer.toString());
+ }
+ return firstToken;
+ }
+}
+
+/**
+ * Implementation of [ConstantEvaluationValidator] used during unit tests;
+ * verifies that any nodes referenced during constant evaluation are present in
+ * the dependency graph.
+ */
+class ConstantEvaluationValidator_ForTest
+ implements ConstantEvaluationValidator {
+ ConstantValueComputer computer;
+
+ ConstantEvaluationTarget _nodeBeingEvaluated;
+
+ @override
+ void beforeComputeValue(ConstantEvaluationTarget constant) {
+ _nodeBeingEvaluated = constant;
+ }
+
+ @override
+ void beforeGetConstantInitializers(ConstructorElement constructor) {
+ // Make sure we properly recorded the dependency.
+ expect(
+ computer.referenceGraph.containsPath(_nodeBeingEvaluated, constructor),
+ isTrue);
+ }
+
+ @override
+ void beforeGetEvaluationResult(ConstantEvaluationTarget constant) {
+ // Make sure we properly recorded the dependency.
+ expect(computer.referenceGraph.containsPath(_nodeBeingEvaluated, constant),
+ isTrue);
+ }
+
+ @override
+ void beforeGetFieldEvaluationResult(FieldElementImpl field) {
+ // Make sure we properly recorded the dependency.
+ expect(computer.referenceGraph.containsPath(_nodeBeingEvaluated, field),
+ isTrue);
+ }
+
+ @override
+ void beforeGetParameterDefault(ParameterElement parameter) {
+ // Make sure we properly recorded the dependency.
+ expect(computer.referenceGraph.containsPath(_nodeBeingEvaluated, parameter),
+ isTrue);
+ }
+}
+
+@reflectiveTest
+class ConstantEvaluatorTest extends ResolverTestCase {
+ void fail_constructor() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_identifier_class() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_identifier_function() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_identifier_static() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_identifier_staticMethod() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_identifier_topLevel() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_identifier_typeParameter() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_prefixedIdentifier_invalid() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_prefixedIdentifier_valid() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_propertyAccess_invalid() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_propertyAccess_valid() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_simpleIdentifier_invalid() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void fail_simpleIdentifier_valid() {
+ EvaluationResult result = _getExpressionValue("?");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, null);
+ }
+
+ void test_bitAnd_int_int() {
+ _assertValue3(74 & 42, "74 & 42");
+ }
+
+ void test_bitNot() {
+ _assertValue3(~42, "~42");
+ }
+
+ void test_bitOr_int_int() {
+ _assertValue3(74 | 42, "74 | 42");
+ }
+
+ void test_bitXor_int_int() {
+ _assertValue3(74 ^ 42, "74 ^ 42");
+ }
+
+ void test_divide_double_double() {
+ _assertValue2(3.2 / 2.3, "3.2 / 2.3");
+ }
+
+ void test_divide_double_double_byZero() {
+ EvaluationResult result = _getExpressionValue("3.2 / 0.0");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value.type.name, "double");
+ expect(value.doubleValue.isInfinite, isTrue);
+ }
+
+ void test_divide_int_int() {
+ _assertValue2(1.5, "3 / 2");
+ }
+
+ void test_divide_int_int_byZero() {
+ EvaluationResult result = _getExpressionValue("3 / 0");
+ expect(result.isValid, isTrue);
+ }
+
+ void test_equal_boolean_boolean() {
+ _assertValue(false, "true == false");
+ }
+
+ void test_equal_int_int() {
+ _assertValue(false, "2 == 3");
+ }
+
+ void test_equal_invalidLeft() {
+ EvaluationResult result = _getExpressionValue("a == 3");
+ expect(result.isValid, isFalse);
+ }
+
+ void test_equal_invalidRight() {
+ EvaluationResult result = _getExpressionValue("2 == a");
+ expect(result.isValid, isFalse);
+ }
+
+ void test_equal_string_string() {
+ _assertValue(false, "'a' == 'b'");
+ }
+
+ void test_greaterThan_int_int() {
+ _assertValue(false, "2 > 3");
+ }
+
+ void test_greaterThanOrEqual_int_int() {
+ _assertValue(false, "2 >= 3");
+ }
+
+ void test_leftShift_int_int() {
+ _assertValue3(64, "16 << 2");
+ }
+
+ void test_lessThan_int_int() {
+ _assertValue(true, "2 < 3");
+ }
+
+ void test_lessThanOrEqual_int_int() {
+ _assertValue(true, "2 <= 3");
+ }
+
+ void test_literal_boolean_false() {
+ _assertValue(false, "false");
+ }
+
+ void test_literal_boolean_true() {
+ _assertValue(true, "true");
+ }
+
+ void test_literal_list() {
+ EvaluationResult result = _getExpressionValue("const ['a', 'b', 'c']");
+ expect(result.isValid, isTrue);
+ }
+
+ void test_literal_map() {
+ EvaluationResult result =
+ _getExpressionValue("const {'a' : 'm', 'b' : 'n', 'c' : 'o'}");
+ expect(result.isValid, isTrue);
+ }
+
+ void test_literal_null() {
+ EvaluationResult result = _getExpressionValue("null");
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value.isNull, isTrue);
+ }
+
+ void test_literal_number_double() {
+ _assertValue2(3.45, "3.45");
+ }
+
+ void test_literal_number_integer() {
+ _assertValue3(42, "42");
+ }
+
+ void test_literal_string_adjacent() {
+ _assertValue4("abcdef", "'abc' 'def'");
+ }
+
+ void test_literal_string_interpolation_invalid() {
+ EvaluationResult result = _getExpressionValue("'a\${f()}c'");
+ expect(result.isValid, isFalse);
+ }
+
+ void test_literal_string_interpolation_valid() {
+ _assertValue4("a3c", "'a\${3}c'");
+ }
+
+ void test_literal_string_simple() {
+ _assertValue4("abc", "'abc'");
+ }
+
+ void test_logicalAnd() {
+ _assertValue(false, "true && false");
+ }
+
+ void test_logicalNot() {
+ _assertValue(false, "!true");
+ }
+
+ void test_logicalOr() {
+ _assertValue(true, "true || false");
+ }
+
+ void test_minus_double_double() {
+ _assertValue2(3.2 - 2.3, "3.2 - 2.3");
+ }
+
+ void test_minus_int_int() {
+ _assertValue3(1, "3 - 2");
+ }
+
+ void test_negated_boolean() {
+ EvaluationResult result = _getExpressionValue("-true");
+ expect(result.isValid, isFalse);
+ }
+
+ void test_negated_double() {
+ _assertValue2(-42.3, "-42.3");
+ }
+
+ void test_negated_integer() {
+ _assertValue3(-42, "-42");
+ }
+
+ void test_notEqual_boolean_boolean() {
+ _assertValue(true, "true != false");
+ }
+
+ void test_notEqual_int_int() {
+ _assertValue(true, "2 != 3");
+ }
+
+ void test_notEqual_invalidLeft() {
+ EvaluationResult result = _getExpressionValue("a != 3");
+ expect(result.isValid, isFalse);
+ }
+
+ void test_notEqual_invalidRight() {
+ EvaluationResult result = _getExpressionValue("2 != a");
+ expect(result.isValid, isFalse);
+ }
+
+ void test_notEqual_string_string() {
+ _assertValue(true, "'a' != 'b'");
+ }
+
+ void test_parenthesizedExpression() {
+ _assertValue4("a", "('a')");
+ }
+
+ void test_plus_double_double() {
+ _assertValue2(2.3 + 3.2, "2.3 + 3.2");
+ }
+
+ void test_plus_int_int() {
+ _assertValue3(5, "2 + 3");
+ }
+
+ void test_plus_string_string() {
+ _assertValue4("ab", "'a' + 'b'");
+ }
+
+ void test_remainder_double_double() {
+ _assertValue2(3.2 % 2.3, "3.2 % 2.3");
+ }
+
+ void test_remainder_int_int() {
+ _assertValue3(2, "8 % 3");
+ }
+
+ void test_rightShift() {
+ _assertValue3(16, "64 >> 2");
+ }
+
+ void test_stringLength_complex() {
+ _assertValue3(6, "('qwe' + 'rty').length");
+ }
+
+ void test_stringLength_simple() {
+ _assertValue3(6, "'Dvorak'.length");
+ }
+
+ void test_times_double_double() {
+ _assertValue2(2.3 * 3.2, "2.3 * 3.2");
+ }
+
+ void test_times_int_int() {
+ _assertValue3(6, "2 * 3");
+ }
+
+ void test_truncatingDivide_double_double() {
+ _assertValue3(1, "3.2 ~/ 2.3");
+ }
+
+ void test_truncatingDivide_int_int() {
+ _assertValue3(3, "10 ~/ 3");
+ }
+
+ void _assertValue(bool expectedValue, String contents) {
+ EvaluationResult result = _getExpressionValue(contents);
+ DartObject value = result.value;
+ expect(value.type.name, "bool");
+ expect(value.boolValue, expectedValue);
+ }
+
+ void _assertValue2(double expectedValue, String contents) {
+ EvaluationResult result = _getExpressionValue(contents);
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value.type.name, "double");
+ expect(value.doubleValue, expectedValue);
+ }
+
+ void _assertValue3(int expectedValue, String contents) {
+ EvaluationResult result = _getExpressionValue(contents);
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value.type.name, "int");
+ expect(value.intValue, expectedValue);
+ }
+
+ void _assertValue4(String expectedValue, String contents) {
+ EvaluationResult result = _getExpressionValue(contents);
+ DartObject value = result.value;
+ expect(value, isNotNull);
+ ParameterizedType type = value.type;
+ expect(type, isNotNull);
+ expect(type.name, "String");
+ expect(value.stringValue, expectedValue);
+ }
+
+ EvaluationResult _getExpressionValue(String contents) {
+ Source source = addSource("var x = $contents;");
+ LibraryElement library = resolve2(source);
+ CompilationUnit unit =
+ analysisContext.resolveCompilationUnit(source, library);
+ expect(unit, isNotNull);
+ NodeList<CompilationUnitMember> declarations = unit.declarations;
+ expect(declarations, hasLength(1));
+ CompilationUnitMember declaration = declarations[0];
+ EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableDeclaration,
+ TopLevelVariableDeclaration, declaration);
+ NodeList<VariableDeclaration> variables =
+ (declaration as TopLevelVariableDeclaration).variables.variables;
+ expect(variables, hasLength(1));
+ ConstantEvaluator evaluator = new ConstantEvaluator(
+ source, analysisContext.typeProvider,
+ typeSystem: analysisContext.typeSystem);
+ return evaluator.evaluate(variables[0].initializer);
+ }
+}
+
+@reflectiveTest
+class ConstantFinderTest extends EngineTestCase {
+ AstNode _node;
+ TypeProvider _typeProvider;
+ AnalysisContext _context;
+ Source _source;
+
+ void setUp() {
+ super.setUp();
+ _typeProvider = new TestTypeProvider();
+ _context = new TestAnalysisContext();
+ _source = new TestSource();
+ }
+
+ /**
+ * Test an annotation that consists solely of an identifier (and hence
+ * represents a reference to a compile-time constant variable).
+ */
+ void test_visitAnnotation_constantVariable() {
+ _node = AstFactory.annotation(AstFactory.identifier3('x'));
+ expect(_findAnnotations(), contains(_node));
+ }
+
+ /**
+ * Test an annotation that represents the invocation of a constant
+ * constructor.
+ */
+ void test_visitAnnotation_invocation() {
+ _node = AstFactory.annotation2(
+ AstFactory.identifier3('A'), null, AstFactory.argumentList());
+ expect(_findAnnotations(), contains(_node));
+ }
+
+ void test_visitConstructorDeclaration_const() {
+ ConstructorElement element = _setupConstructorDeclaration("A", true);
+ expect(_findConstants(), contains(element));
+ }
+
+ void test_visitConstructorDeclaration_nonConst() {
+ _setupConstructorDeclaration("A", false);
+ expect(_findConstants(), isEmpty);
+ }
+
+ void test_visitVariableDeclaration_const() {
+ VariableElement element = _setupVariableDeclaration("v", true, true);
+ expect(_findConstants(), contains(element));
+ }
+
+ void test_visitVariableDeclaration_final_inClass() {
+ _setupFieldDeclaration('C', 'f', Keyword.FINAL);
+ expect(_findConstants(), isEmpty);
+ }
+
+ void test_visitVariableDeclaration_final_inClassWithConstConstructor() {
+ VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
+ hasConstConstructor: true);
+ expect(_findConstants(), contains(field.element));
+ }
+
+ void test_visitVariableDeclaration_final_outsideClass() {
+ _setupVariableDeclaration('v', false, true, isFinal: true);
+ expect(_findConstants(), isEmpty);
+ }
+
+ void test_visitVariableDeclaration_noInitializer() {
+ _setupVariableDeclaration("v", true, false);
+ expect(_findConstants(), isEmpty);
+ }
+
+ void test_visitVariableDeclaration_nonConst() {
+ _setupVariableDeclaration("v", false, true);
+ expect(_findConstants(), isEmpty);
+ }
+
+ void test_visitVariableDeclaration_static_const_inClass() {
+ VariableDeclaration field =
+ _setupFieldDeclaration('C', 'f', Keyword.CONST, isStatic: true);
+ expect(_findConstants(), contains(field.element));
+ }
+
+ void test_visitVariableDeclaration_static_const_inClassWithConstConstructor() {
+ VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.CONST,
+ isStatic: true, hasConstConstructor: true);
+ expect(_findConstants(), contains(field.element));
+ }
+
+ void test_visitVariableDeclaration_static_final_inClassWithConstConstructor() {
+ VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
+ isStatic: true, hasConstConstructor: true);
+ expect(_findConstants(), isNot(contains(field.element)));
+ }
+
+ void test_visitVariableDeclaration_uninitialized_final_inClassWithConstConstructor() {
+ VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
+ isInitialized: false, hasConstConstructor: true);
+ expect(_findConstants(), isNot(contains(field.element)));
+ }
+
+ void test_visitVariableDeclaration_uninitialized_static_const_inClass() {
+ _setupFieldDeclaration('C', 'f', Keyword.CONST,
+ isStatic: true, isInitialized: false);
+ expect(_findConstants(), isEmpty);
+ }
+
+ List<Annotation> _findAnnotations() {
+ Set<Annotation> annotations = new Set<Annotation>();
+ for (ConstantEvaluationTarget target in _findConstants()) {
+ if (target is ConstantEvaluationTarget_Annotation) {
+ expect(target.context, same(_context));
+ expect(target.source, same(_source));
+ annotations.add(target.annotation);
+ }
+ }
+ return new List<Annotation>.from(annotations);
+ }
+
+ Set<ConstantEvaluationTarget> _findConstants() {
+ ConstantFinder finder = new ConstantFinder(_context, _source, _source);
+ _node.accept(finder);
+ Set<ConstantEvaluationTarget> constants = finder.constantsToCompute;
+ expect(constants, isNotNull);
+ return constants;
+ }
+
+ ConstructorElement _setupConstructorDeclaration(String name, bool isConst) {
+ Keyword constKeyword = isConst ? Keyword.CONST : null;
+ ConstructorDeclaration constructorDeclaration = AstFactory
+ .constructorDeclaration2(
+ constKeyword,
+ null,
+ null,
+ name,
+ AstFactory.formalParameterList(),
+ null,
+ AstFactory.blockFunctionBody2());
+ ClassElement classElement = ElementFactory.classElement2(name);
+ ConstructorElement element =
+ ElementFactory.constructorElement(classElement, name, isConst);
+ constructorDeclaration.element = element;
+ _node = constructorDeclaration;
+ return element;
+ }
+
+ VariableDeclaration _setupFieldDeclaration(
+ String className, String fieldName, Keyword keyword,
+ {bool isInitialized: true,
+ bool isStatic: false,
+ bool hasConstConstructor: false}) {
+ VariableDeclaration variableDeclaration = isInitialized
+ ? AstFactory.variableDeclaration2(fieldName, AstFactory.integer(0))
+ : AstFactory.variableDeclaration(fieldName);
+ VariableElement fieldElement = ElementFactory.fieldElement(
+ fieldName,
+ isStatic,
+ keyword == Keyword.FINAL,
+ keyword == Keyword.CONST,
+ _typeProvider.intType);
+ variableDeclaration.name.staticElement = fieldElement;
+ FieldDeclaration fieldDeclaration = AstFactory.fieldDeclaration2(
+ isStatic, keyword, <VariableDeclaration>[variableDeclaration]);
+ ClassDeclaration classDeclaration =
+ AstFactory.classDeclaration(null, className, null, null, null, null);
+ classDeclaration.members.add(fieldDeclaration);
+ _node = classDeclaration;
+ ClassElementImpl classElement = ElementFactory.classElement2(className);
+ classElement.fields = <FieldElement>[fieldElement];
+ classDeclaration.name.staticElement = classElement;
+ if (hasConstConstructor) {
+ ConstructorDeclaration constructorDeclaration = AstFactory
+ .constructorDeclaration2(
+ Keyword.CONST,
+ null,
+ AstFactory.identifier3(className),
+ null,
+ AstFactory.formalParameterList(),
+ null,
+ AstFactory.blockFunctionBody2());
+ classDeclaration.members.add(constructorDeclaration);
+ ConstructorElement constructorElement =
+ ElementFactory.constructorElement(classElement, '', true);
+ constructorDeclaration.element = constructorElement;
+ classElement.constructors = <ConstructorElement>[constructorElement];
+ } else {
+ classElement.constructors = ConstructorElement.EMPTY_LIST;
+ }
+ return variableDeclaration;
+ }
+
+ VariableElement _setupVariableDeclaration(
+ String name, bool isConst, bool isInitialized,
+ {isFinal: false}) {
+ VariableDeclaration variableDeclaration = isInitialized
+ ? AstFactory.variableDeclaration2(name, AstFactory.integer(0))
+ : AstFactory.variableDeclaration(name);
+ SimpleIdentifier identifier = variableDeclaration.name;
+ VariableElement element = ElementFactory.localVariableElement(identifier);
+ identifier.staticElement = element;
+ Keyword keyword = isConst ? Keyword.CONST : isFinal ? Keyword.FINAL : null;
+ AstFactory.variableDeclarationList2(keyword, [variableDeclaration]);
+ _node = variableDeclaration;
+ return element;
+ }
+}
+
+@reflectiveTest
+class ConstantValueComputerTest extends ResolverTestCase {
+ void test_annotation_constConstructor() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+ final int i;
+ const A(this.i);
+}
+
+class C {
+ @A(5)
+ f() {}
+}
+''');
+ EvaluationResultImpl result =
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ Map<String, DartObjectImpl> annotationFields = _assertType(result, 'A');
+ _assertIntField(annotationFields, 'i', 5);
+ }
+
+ void test_annotation_constConstructor_named() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+ final int i;
+ const A.named(this.i);
+}
+
+class C {
+ @A.named(5)
+ f() {}
+}
+''');
+ EvaluationResultImpl result =
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ Map<String, DartObjectImpl> annotationFields = _assertType(result, 'A');
+ _assertIntField(annotationFields, 'i', 5);
+ }
+
+ void test_annotation_constConstructor_noArgs() {
+ // Failing to pass arguments to an annotation which is a constant
+ // constructor is illegal, but shouldn't crash analysis.
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+ final int i;
+ const A(this.i);
+}
+
+class C {
+ @A
+ f() {}
+}
+''');
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ }
+
+ void test_annotation_constConstructor_noArgs_named() {
+ // Failing to pass arguments to an annotation which is a constant
+ // constructor is illegal, but shouldn't crash analysis.
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+ final int i;
+ const A.named(this.i);
+}
+
+class C {
+ @A.named
+ f() {}
+}
+''');
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ }
+
+ void test_annotation_nonConstConstructor() {
+ // Calling a non-const constructor from an annotation that is illegal, but
+ // shouldn't crash analysis.
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+ final int i;
+ A(this.i);
+}
+
+class C {
+ @A(5)
+ f() {}
+}
+''');
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ }
+
+ void test_annotation_staticConst() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+class C {
+ static const int i = 5;
+
+ @i
+ f() {}
+}
+''');
+ EvaluationResultImpl result =
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ expect(_assertValidInt(result), 5);
+ }
+
+ void test_annotation_staticConst_args() {
+ // Applying arguments to an annotation that is a static const is
+ // illegal, but shouldn't crash analysis.
+ CompilationUnit compilationUnit = resolveSource(r'''
+class C {
+ static const int i = 5;
+
+ @i(1)
+ f() {}
+}
+''');
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ }
+
+ void test_annotation_staticConst_otherClass() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+ static const int i = 5;
+}
+
+class C {
+ @A.i
+ f() {}
+}
+''');
+ EvaluationResultImpl result =
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ expect(_assertValidInt(result), 5);
+ }
+
+ void test_annotation_staticConst_otherClass_args() {
+ // Applying arguments to an annotation that is a static const is
+ // illegal, but shouldn't crash analysis.
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+ static const int i = 5;
+}
+
+class C {
+ @A.i(1)
+ f() {}
+}
+''');
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ }
+
+ void test_annotation_toplevelVariable() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const int i = 5;
+class C {
+ @i
+ f() {}
+}
+''');
+ EvaluationResultImpl result =
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ expect(_assertValidInt(result), 5);
+ }
+
+ void test_annotation_toplevelVariable_args() {
+ // Applying arguments to an annotation that is a toplevel variable is
+ // illegal, but shouldn't crash analysis.
+ CompilationUnit compilationUnit = resolveSource(r'''
+const int i = 5;
+class C {
+ @i(1)
+ f() {}
+}
+''');
+ _evaluateAnnotation(compilationUnit, "C", "f");
+ }
+
+ void test_computeValues_cycle() {
+ TestLogger logger = new TestLogger();
+ AnalysisEngine.instance.logger = logger;
+ Source librarySource = addSource(r'''
+const int a = c;
+const int b = a;
+const int c = b;''');
+ LibraryElement libraryElement = resolve2(librarySource);
+ CompilationUnit unit =
+ analysisContext.resolveCompilationUnit(librarySource, libraryElement);
+ analysisContext.computeErrors(librarySource);
+ expect(unit, isNotNull);
+ ConstantValueComputer computer = _makeConstantValueComputer();
+ computer.add(unit, librarySource, librarySource);
+ computer.computeValues();
+ NodeList<CompilationUnitMember> members = unit.declarations;
+ expect(members, hasLength(3));
+ _validate(false, (members[0] as TopLevelVariableDeclaration).variables);
+ _validate(false, (members[1] as TopLevelVariableDeclaration).variables);
+ _validate(false, (members[2] as TopLevelVariableDeclaration).variables);
+ }
+
+ void test_computeValues_dependentVariables() {
+ Source librarySource = addSource(r'''
+const int b = a;
+const int a = 0;''');
+ LibraryElement libraryElement = resolve2(librarySource);
+ CompilationUnit unit =
+ analysisContext.resolveCompilationUnit(librarySource, libraryElement);
+ expect(unit, isNotNull);
+ ConstantValueComputer computer = _makeConstantValueComputer();
+ computer.add(unit, librarySource, librarySource);
+ computer.computeValues();
+ NodeList<CompilationUnitMember> members = unit.declarations;
+ expect(members, hasLength(2));
+ _validate(true, (members[0] as TopLevelVariableDeclaration).variables);
+ _validate(true, (members[1] as TopLevelVariableDeclaration).variables);
+ }
+
+ void test_computeValues_empty() {
+ ConstantValueComputer computer = _makeConstantValueComputer();
+ computer.computeValues();
+ }
+
+ void test_computeValues_multipleSources() {
+ Source librarySource = addNamedSource(
+ "/lib.dart",
+ r'''
+library lib;
+part 'part.dart';
+const int c = b;
+const int a = 0;''');
+ Source partSource = addNamedSource(
+ "/part.dart",
+ r'''
+part of lib;
+const int b = a;
+const int d = c;''');
+ LibraryElement libraryElement = resolve2(librarySource);
+ CompilationUnit libraryUnit =
+ analysisContext.resolveCompilationUnit(librarySource, libraryElement);
+ expect(libraryUnit, isNotNull);
+ CompilationUnit partUnit =
+ analysisContext.resolveCompilationUnit(partSource, libraryElement);
+ expect(partUnit, isNotNull);
+ ConstantValueComputer computer = _makeConstantValueComputer();
+ computer.add(libraryUnit, librarySource, librarySource);
+ computer.add(partUnit, partSource, librarySource);
+ computer.computeValues();
+ NodeList<CompilationUnitMember> libraryMembers = libraryUnit.declarations;
+ expect(libraryMembers, hasLength(2));
+ _validate(
+ true, (libraryMembers[0] as TopLevelVariableDeclaration).variables);
+ _validate(
+ true, (libraryMembers[1] as TopLevelVariableDeclaration).variables);
+ NodeList<CompilationUnitMember> partMembers = libraryUnit.declarations;
+ expect(partMembers, hasLength(2));
+ _validate(true, (partMembers[0] as TopLevelVariableDeclaration).variables);
+ _validate(true, (partMembers[1] as TopLevelVariableDeclaration).variables);
+ }
+
+ void test_computeValues_singleVariable() {
+ Source librarySource = addSource("const int a = 0;");
+ LibraryElement libraryElement = resolve2(librarySource);
+ CompilationUnit unit =
+ analysisContext.resolveCompilationUnit(librarySource, libraryElement);
+ expect(unit, isNotNull);
+ ConstantValueComputer computer = _makeConstantValueComputer();
+ computer.add(unit, librarySource, librarySource);
+ computer.computeValues();
+ NodeList<CompilationUnitMember> members = unit.declarations;
+ expect(members, hasLength(1));
+ _validate(true, (members[0] as TopLevelVariableDeclaration).variables);
+ }
+
+ void test_computeValues_value_depends_on_enum() {
+ Source librarySource = addSource('''
+enum E { id0, id1 }
+const E e = E.id0;
+''');
+ LibraryElement libraryElement = resolve2(librarySource);
+ CompilationUnit unit =
+ analysisContext.resolveCompilationUnit(librarySource, libraryElement);
+ expect(unit, isNotNull);
+ ConstantValueComputer computer = _makeConstantValueComputer();
+ computer.add(unit, librarySource, librarySource);
+ computer.computeValues();
+ TopLevelVariableDeclaration declaration = unit.declarations
+ .firstWhere((member) => member is TopLevelVariableDeclaration);
+ _validate(true, declaration.variables);
+ }
+
+ void test_dependencyOnConstructor() {
+ // x depends on "const A()"
+ _assertProperDependencies(r'''
+class A {
+ const A();
+}
+const x = const A();''');
+ }
+
+ void test_dependencyOnConstructorArgument() {
+ // "const A(x)" depends on x
+ _assertProperDependencies(r'''
+class A {
+ const A(this.next);
+ final A next;
+}
+const A x = const A(null);
+const A y = const A(x);''');
+ }
+
+ void test_dependencyOnConstructorArgument_unresolvedConstructor() {
+ // "const A.a(x)" depends on x even if the constructor A.a can't be found.
+ _assertProperDependencies(
+ r'''
+class A {
+}
+const int x = 1;
+const A y = const A.a(x);''',
+ [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
+ }
+
+ void test_dependencyOnConstructorInitializer() {
+ // "const A()" depends on x
+ _assertProperDependencies(r'''
+const int x = 1;
+class A {
+ const A() : v = x;
+ final int v;
+}''');
+ }
+
+ void test_dependencyOnExplicitSuperConstructor() {
+ // b depends on B() depends on A()
+ _assertProperDependencies(r'''
+class A {
+ const A(this.x);
+ final int x;
+}
+class B extends A {
+ const B() : super(5);
+}
+const B b = const B();''');
+ }
+
+ void test_dependencyOnExplicitSuperConstructorParameters() {
+ // b depends on B() depends on i
+ _assertProperDependencies(r'''
+class A {
+ const A(this.x);
+ final int x;
+}
+class B extends A {
+ const B() : super(i);
+}
+const B b = const B();
+const int i = 5;''');
+ }
+
+ void test_dependencyOnFactoryRedirect() {
+ // a depends on A.foo() depends on A.bar()
+ _assertProperDependencies(r'''
+const A a = const A.foo();
+class A {
+ factory const A.foo() = A.bar;
+ const A.bar();
+}''');
+ }
+
+ void test_dependencyOnFactoryRedirectWithTypeParams() {
+ _assertProperDependencies(r'''
+class A {
+ const factory A(var a) = B<int>;
+}
+
+class B<T> implements A {
+ final T x;
+ const B(this.x);
+}
+
+const A a = const A(10);''');
+ }
+
+ void test_dependencyOnImplicitSuperConstructor() {
+ // b depends on B() depends on A()
+ _assertProperDependencies(r'''
+class A {
+ const A() : x = 5;
+ final int x;
+}
+class B extends A {
+ const B();
+}
+const B b = const B();''');
+ }
+
+ void test_dependencyOnInitializedFinal() {
+ // a depends on A() depends on A.x
+ _assertProperDependencies('''
+class A {
+ const A();
+ final int x = 1;
+}
+const A a = const A();
+''');
+ }
+
+ void test_dependencyOnInitializedNonStaticConst() {
+ // Even though non-static consts are not allowed by the language, we need
+ // to handle them for error recovery purposes.
+ // a depends on A() depends on A.x
+ _assertProperDependencies(
+ '''
+class A {
+ const A();
+ const int x = 1;
+}
+const A a = const A();
+''',
+ [CompileTimeErrorCode.CONST_INSTANCE_FIELD]);
+ }
+
+ void test_dependencyOnNonFactoryRedirect() {
+ // a depends on A.foo() depends on A.bar()
+ _assertProperDependencies(r'''
+const A a = const A.foo();
+class A {
+ const A.foo() : this.bar();
+ const A.bar();
+}''');
+ }
+
+ void test_dependencyOnNonFactoryRedirect_arg() {
+ // a depends on A.foo() depends on b
+ _assertProperDependencies(r'''
+const A a = const A.foo();
+const int b = 1;
+class A {
+ const A.foo() : this.bar(b);
+ const A.bar(x) : y = x;
+ final int y;
+}''');
+ }
+
+ void test_dependencyOnNonFactoryRedirect_defaultValue() {
+ // a depends on A.foo() depends on A.bar() depends on b
+ _assertProperDependencies(r'''
+const A a = const A.foo();
+const int b = 1;
+class A {
+ const A.foo() : this.bar();
+ const A.bar([x = b]) : y = x;
+ final int y;
+}''');
+ }
+
+ void test_dependencyOnNonFactoryRedirect_toMissing() {
+ // a depends on A.foo() which depends on nothing, since A.bar() is
+ // missing.
+ _assertProperDependencies(
+ r'''
+const A a = const A.foo();
+class A {
+ const A.foo() : this.bar();
+}''',
+ [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR]);
+ }
+
+ void test_dependencyOnNonFactoryRedirect_toNonConst() {
+ // a depends on A.foo() which depends on nothing, since A.bar() is
+ // non-const.
+ _assertProperDependencies(r'''
+const A a = const A.foo();
+class A {
+ const A.foo() : this.bar();
+ A.bar();
+}''');
+ }
+
+ void test_dependencyOnNonFactoryRedirect_unnamed() {
+ // a depends on A.foo() depends on A()
+ _assertProperDependencies(r'''
+const A a = const A.foo();
+class A {
+ const A.foo() : this();
+ const A();
+}''');
+ }
+
+ void test_dependencyOnOptionalParameterDefault() {
+ // a depends on A() depends on B()
+ _assertProperDependencies(r'''
+class A {
+ const A([x = const B()]) : b = x;
+ final B b;
+}
+class B {
+ const B();
+}
+const A a = const A();''');
+ }
+
+ void test_dependencyOnVariable() {
+ // x depends on y
+ _assertProperDependencies(r'''
+const x = y + 1;
+const y = 2;''');
+ }
+
+ void test_final_initialized_at_declaration() {
+ CompilationUnit compilationUnit = resolveSource('''
+class A {
+ final int i = 123;
+ const A();
+}
+
+const A a = const A();
+''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, 'a');
+ Map<String, DartObjectImpl> fields = _assertType(result, "A");
+ expect(fields, hasLength(1));
+ _assertIntField(fields, "i", 123);
+ }
+
+ void test_fromEnvironment_bool_default_false() {
+ expect(_assertValidBool(_check_fromEnvironment_bool(null, "false")), false);
+ }
+
+ void test_fromEnvironment_bool_default_overridden() {
+ expect(
+ _assertValidBool(_check_fromEnvironment_bool("false", "true")), false);
+ }
+
+ void test_fromEnvironment_bool_default_parseError() {
+ expect(_assertValidBool(_check_fromEnvironment_bool("parseError", "true")),
+ true);
+ }
+
+ void test_fromEnvironment_bool_default_true() {
+ expect(_assertValidBool(_check_fromEnvironment_bool(null, "true")), true);
+ }
+
+ void test_fromEnvironment_bool_false() {
+ expect(_assertValidBool(_check_fromEnvironment_bool("false", null)), false);
+ }
+
+ void test_fromEnvironment_bool_parseError() {
+ expect(_assertValidBool(_check_fromEnvironment_bool("parseError", null)),
+ false);
+ }
+
+ void test_fromEnvironment_bool_true() {
+ expect(_assertValidBool(_check_fromEnvironment_bool("true", null)), true);
+ }
+
+ void test_fromEnvironment_bool_undeclared() {
+ _assertValidUnknown(_check_fromEnvironment_bool(null, null));
+ }
+
+ void test_fromEnvironment_int_default_overridden() {
+ expect(_assertValidInt(_check_fromEnvironment_int("234", "123")), 234);
+ }
+
+ void test_fromEnvironment_int_default_parseError() {
+ expect(
+ _assertValidInt(_check_fromEnvironment_int("parseError", "123")), 123);
+ }
+
+ void test_fromEnvironment_int_default_undeclared() {
+ expect(_assertValidInt(_check_fromEnvironment_int(null, "123")), 123);
+ }
+
+ void test_fromEnvironment_int_ok() {
+ expect(_assertValidInt(_check_fromEnvironment_int("234", null)), 234);
+ }
+
+ void test_fromEnvironment_int_parseError() {
+ _assertValidNull(_check_fromEnvironment_int("parseError", null));
+ }
+
+ void test_fromEnvironment_int_parseError_nullDefault() {
+ _assertValidNull(_check_fromEnvironment_int("parseError", "null"));
+ }
+
+ void test_fromEnvironment_int_undeclared() {
+ _assertValidUnknown(_check_fromEnvironment_int(null, null));
+ }
+
+ void test_fromEnvironment_int_undeclared_nullDefault() {
+ _assertValidNull(_check_fromEnvironment_int(null, "null"));
+ }
+
+ void test_fromEnvironment_string_default_overridden() {
+ expect(_assertValidString(_check_fromEnvironment_string("abc", "'def'")),
+ "abc");
+ }
+
+ void test_fromEnvironment_string_default_undeclared() {
+ expect(_assertValidString(_check_fromEnvironment_string(null, "'def'")),
+ "def");
+ }
+
+ void test_fromEnvironment_string_empty() {
+ expect(_assertValidString(_check_fromEnvironment_string("", null)), "");
+ }
+
+ void test_fromEnvironment_string_ok() {
+ expect(
+ _assertValidString(_check_fromEnvironment_string("abc", null)), "abc");
+ }
+
+ void test_fromEnvironment_string_undeclared() {
+ _assertValidUnknown(_check_fromEnvironment_string(null, null));
+ }
+
+ void test_fromEnvironment_string_undeclared_nullDefault() {
+ _assertValidNull(_check_fromEnvironment_string(null, "null"));
+ }
+
+ void test_instanceCreationExpression_computedField() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(4, 5);
+class A {
+ const A(int i, int j) : k = 2 * i + j;
+ final int k;
+}''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "foo");
+ Map<String, DartObjectImpl> fields = _assertType(result, "A");
+ expect(fields, hasLength(1));
+ _assertIntField(fields, "k", 13);
+ }
+
+ void test_instanceCreationExpression_computedField_namedOptionalWithDefault() {
+ _checkInstanceCreationOptionalParams(false, true, true);
+ }
+
+ void test_instanceCreationExpression_computedField_namedOptionalWithoutDefault() {
+ _checkInstanceCreationOptionalParams(false, true, false);
+ }
+
+ void test_instanceCreationExpression_computedField_unnamedOptionalWithDefault() {
+ _checkInstanceCreationOptionalParams(false, false, true);
+ }
+
+ void test_instanceCreationExpression_computedField_unnamedOptionalWithoutDefault() {
+ _checkInstanceCreationOptionalParams(false, false, false);
+ }
+
+ void test_instanceCreationExpression_computedField_usesConstConstructor() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(3);
+class A {
+ const A(int i) : b = const B(4);
+ final int b;
+}
+class B {
+ const B(this.k);
+ final int k;
+}''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "foo");
+ Map<String, DartObjectImpl> fieldsOfA = _assertType(result, "A");
+ expect(fieldsOfA, hasLength(1));
+ Map<String, DartObjectImpl> fieldsOfB =
+ _assertFieldType(fieldsOfA, "b", "B");
+ expect(fieldsOfB, hasLength(1));
+ _assertIntField(fieldsOfB, "k", 4);
+ }
+
+ void test_instanceCreationExpression_computedField_usesStaticConst() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(3);
+class A {
+ const A(int i) : k = i + B.bar;
+ final int k;
+}
+class B {
+ static const bar = 4;
+}''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "foo");
+ Map<String, DartObjectImpl> fields = _assertType(result, "A");
+ expect(fields, hasLength(1));
+ _assertIntField(fields, "k", 7);
+ }
+
+ void test_instanceCreationExpression_computedField_usesToplevelConst() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(3);
+const bar = 4;
+class A {
+ const A(int i) : k = i + bar;
+ final int k;
+}''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "foo");
+ Map<String, DartObjectImpl> fields = _assertType(result, "A");
+ expect(fields, hasLength(1));
+ _assertIntField(fields, "k", 7);
+ }
+
+ void test_instanceCreationExpression_explicitSuper() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const B(4, 5);
+class A {
+ const A(this.x);
+ final int x;
+}
+class B extends A {
+ const B(int x, this.y) : super(x * 2);
+ final int y;
+}''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "foo");
+ Map<String, DartObjectImpl> fields = _assertType(result, "B");
+ expect(fields, hasLength(2));
+ _assertIntField(fields, "y", 5);
+ Map<String, DartObjectImpl> superclassFields =
+ _assertFieldType(fields, GenericState.SUPERCLASS_FIELD, "A");
+ expect(superclassFields, hasLength(1));
+ _assertIntField(superclassFields, "x", 8);
+ }
+
+ void test_instanceCreationExpression_fieldFormalParameter() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(42);
+class A {
+ int x;
+ const A(this.x)
+}''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "foo");
+ Map<String, DartObjectImpl> fields = _assertType(result, "A");
+ expect(fields, hasLength(1));
+ _assertIntField(fields, "x", 42);
+ }
+
+ void test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithDefault() {
+ _checkInstanceCreationOptionalParams(true, true, true);
+ }
+
+ void test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithoutDefault() {
+ _checkInstanceCreationOptionalParams(true, true, false);
+ }
+
+ void test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithDefault() {
+ _checkInstanceCreationOptionalParams(true, false, true);
+ }
+
+ void test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithoutDefault() {
+ _checkInstanceCreationOptionalParams(true, false, false);
+ }
+
+ void test_instanceCreationExpression_implicitSuper() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const B(4);
+class A {
+ const A() : x = 3;
+ final int x;
+}
+class B extends A {
+ const B(this.y);
+ final int y;
+}''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "foo");
+ Map<String, DartObjectImpl> fields = _assertType(result, "B");
+ expect(fields, hasLength(2));
+ _assertIntField(fields, "y", 4);
+ Map<String, DartObjectImpl> superclassFields =
+ _assertFieldType(fields, GenericState.SUPERCLASS_FIELD, "A");
+ expect(superclassFields, hasLength(1));
+ _assertIntField(superclassFields, "x", 3);
+ }
+
+ void test_instanceCreationExpression_nonFactoryRedirect() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+ const A.a1() : this.a2();
+ const A.a2() : x = 5;
+ final int x;
+}''');
+ Map<String, DartObjectImpl> aFields =
+ _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+ _assertIntField(aFields, 'x', 5);
+ }
+
+ void test_instanceCreationExpression_nonFactoryRedirect_arg() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1(1);
+class A {
+ const A.a1(x) : this.a2(x + 100);
+ const A.a2(x) : y = x + 10;
+ final int y;
+}''');
+ Map<String, DartObjectImpl> aFields =
+ _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+ _assertIntField(aFields, 'y', 111);
+ }
+
+ void test_instanceCreationExpression_nonFactoryRedirect_cycle() {
+ // It is an error to have a cycle in non-factory redirects; however, we
+ // need to make sure that even if the error occurs, attempting to evaluate
+ // the constant will terminate.
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+ const A() : this.b();
+ const A.b() : this();
+}''');
+ _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
+ }
+
+ void test_instanceCreationExpression_nonFactoryRedirect_defaultArg() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+ const A.a1() : this.a2();
+ const A.a2([x = 100]) : y = x + 10;
+ final int y;
+}''');
+ Map<String, DartObjectImpl> aFields =
+ _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+ _assertIntField(aFields, 'y', 110);
+ }
+
+ void test_instanceCreationExpression_nonFactoryRedirect_toMissing() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+ const A.a1() : this.a2();
+}''');
+ // We don't care what value foo evaluates to (since there is a compile
+ // error), but we shouldn't crash, and we should figure
+ // out that it evaluates to an instance of class A.
+ _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+ }
+
+ void test_instanceCreationExpression_nonFactoryRedirect_toNonConst() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+ const A.a1() : this.a2();
+ A.a2();
+}''');
+ // We don't care what value foo evaluates to (since there is a compile
+ // error), but we shouldn't crash, and we should figure
+ // out that it evaluates to an instance of class A.
+ _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+ }
+
+ void test_instanceCreationExpression_nonFactoryRedirect_unnamed() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+ const A.a1() : this();
+ const A() : x = 5;
+ final int x;
+}''');
+ Map<String, DartObjectImpl> aFields =
+ _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+ _assertIntField(aFields, 'x', 5);
+ }
+
+ void test_instanceCreationExpression_redirect() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+ const factory A() = B;
+}
+class B implements A {
+ const B();
+}''');
+ _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "B");
+ }
+
+ void test_instanceCreationExpression_redirect_cycle() {
+ // It is an error to have a cycle in factory redirects; however, we need
+ // to make sure that even if the error occurs, attempting to evaluate the
+ // constant will terminate.
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+ const factory A() = A.b;
+ const factory A.b() = A;
+}''');
+ _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
+ }
+
+ void test_instanceCreationExpression_redirect_extern() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+ external const factory A();
+}''');
+ _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
+ }
+
+ void test_instanceCreationExpression_redirect_nonConst() {
+ // It is an error for a const factory constructor redirect to a non-const
+ // constructor; however, we need to make sure that even if the error
+ // attempting to evaluate the constant won't cause a crash.
+ CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+ const factory A() = A.b;
+ A.b();
+}''');
+ _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
+ }
+
+ void test_instanceCreationExpression_redirectWithTypeParams() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+ const factory A(var a) = B<int>;
+}
+
+class B<T> implements A {
+ final T x;
+ const B(this.x);
+}
+
+const A a = const A(10);''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "a");
+ Map<String, DartObjectImpl> fields = _assertType(result, "B<int>");
+ expect(fields, hasLength(1));
+ _assertIntField(fields, "x", 10);
+ }
+
+ void test_instanceCreationExpression_redirectWithTypeSubstitution() {
+ // To evaluate the redirection of A<int>,
+ // A's template argument (T=int) must be substituted
+ // into B's template argument (B<U> where U=T) to get B<int>.
+ CompilationUnit compilationUnit = resolveSource(r'''
+class A<T> {
+ const factory A(var a) = B<T>;
+}
+
+class B<U> implements A {
+ final U x;
+ const B(this.x);
+}
+
+const A<int> a = const A<int>(10);''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, "a");
+ Map<String, DartObjectImpl> fields = _assertType(result, "B<int>");
+ expect(fields, hasLength(1));
+ _assertIntField(fields, "x", 10);
+ }
+
+ void test_instanceCreationExpression_symbol() {
+ CompilationUnit compilationUnit =
+ resolveSource("const foo = const Symbol('a');");
+ EvaluationResultImpl evaluationResult =
+ _evaluateTopLevelVariable(compilationUnit, "foo");
+ expect(evaluationResult.value, isNotNull);
+ DartObjectImpl value = evaluationResult.value;
+ expect(value.type, typeProvider.symbolType);
+ expect(value.value, "a");
+ }
+
+ void test_instanceCreationExpression_withSupertypeParams_explicit() {
+ _checkInstanceCreation_withSupertypeParams(true);
+ }
+
+ void test_instanceCreationExpression_withSupertypeParams_implicit() {
+ _checkInstanceCreation_withSupertypeParams(false);
+ }
+
+ void test_instanceCreationExpression_withTypeParams() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+class C<E> {
+ const C();
+}
+const c_int = const C<int>();
+const c_num = const C<num>();''');
+ EvaluationResultImpl c_int =
+ _evaluateTopLevelVariable(compilationUnit, "c_int");
+ _assertType(c_int, "C<int>");
+ DartObjectImpl c_int_value = c_int.value;
+ EvaluationResultImpl c_num =
+ _evaluateTopLevelVariable(compilationUnit, "c_num");
+ _assertType(c_num, "C<num>");
+ DartObjectImpl c_num_value = c_num.value;
+ expect(c_int_value == c_num_value, isFalse);
+ }
+
+ void test_isValidSymbol() {
+ expect(ConstantEvaluationEngine.isValidPublicSymbol(""), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.bar"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo\$"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo\$bar"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("iff"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("gif"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("if\$"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("\$if"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo="), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.bar="), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.+"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("void"), isTrue);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("_foo"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("_foo.bar"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo._bar"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("if"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("if.foo"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.if"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo=.bar"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo."), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("+.foo"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("void.foo"), isFalse);
+ expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.void"), isFalse);
+ }
+
+ void test_length_of_improperly_typed_string_expression() {
+ // Since type annotations are ignored in unchecked mode, the improper
+ // types on s1 and s2 shouldn't prevent us from evaluating i to
+ // 'alpha'.length.
+ CompilationUnit compilationUnit = resolveSource('''
+const int s1 = 'alpha';
+const int s2 = 'beta';
+const int i = (true ? s1 : s2).length;
+''');
+ ConstTopLevelVariableElementImpl element =
+ findTopLevelDeclaration(compilationUnit, 'i').element;
+ EvaluationResultImpl result = element.evaluationResult;
+ expect(_assertValidInt(result), 5);
+ }
+
+ void test_length_of_improperly_typed_string_identifier() {
+ // Since type annotations are ignored in unchecked mode, the improper type
+ // on s shouldn't prevent us from evaluating i to 'alpha'.length.
+ CompilationUnit compilationUnit = resolveSource('''
+const int s = 'alpha';
+const int i = s.length;
+''');
+ ConstTopLevelVariableElementImpl element =
+ findTopLevelDeclaration(compilationUnit, 'i').element;
+ EvaluationResultImpl result = element.evaluationResult;
+ expect(_assertValidInt(result), 5);
+ }
+
+ void test_non_static_const_initialized_at_declaration() {
+ // Even though non-static consts are not allowed by the language, we need
+ // to handle them for error recovery purposes.
+ CompilationUnit compilationUnit = resolveSource('''
+class A {
+ const int i = 123;
+ const A();
+}
+
+const A a = const A();
+''');
+ EvaluationResultImpl result =
+ _evaluateTopLevelVariable(compilationUnit, 'a');
+ Map<String, DartObjectImpl> fields = _assertType(result, "A");
+ expect(fields, hasLength(1));
+ _assertIntField(fields, "i", 123);
+ }
+
+ void test_symbolLiteral_void() {
+ CompilationUnit compilationUnit =
+ resolveSource("const voidSymbol = #void;");
+ VariableDeclaration voidSymbol =
+ findTopLevelDeclaration(compilationUnit, "voidSymbol");
+ EvaluationResultImpl voidSymbolResult =
+ (voidSymbol.element as VariableElementImpl).evaluationResult;
+ DartObjectImpl value = voidSymbolResult.value;
+ expect(value.type, typeProvider.symbolType);
+ expect(value.value, "void");
+ }
+
+ Map<String, DartObjectImpl> _assertFieldType(
+ Map<String, DartObjectImpl> fields,
+ String fieldName,
+ String expectedType) {
+ DartObjectImpl field = fields[fieldName];
+ expect(field.type.displayName, expectedType);
+ return field.fields;
+ }
+
+ void _assertIntField(
+ Map<String, DartObjectImpl> fields, String fieldName, int expectedValue) {
+ DartObjectImpl field = fields[fieldName];
+ expect(field.type.name, "int");
+ expect(field.intValue, expectedValue);
+ }
+
+ void _assertNullField(Map<String, DartObjectImpl> fields, String fieldName) {
+ DartObjectImpl field = fields[fieldName];
+ expect(field.isNull, isTrue);
+ }
+
+ void _assertProperDependencies(String sourceText,
+ [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
+ Source source = addSource(sourceText);
+ LibraryElement element = resolve2(source);
+ CompilationUnit unit =
+ analysisContext.resolveCompilationUnit(source, element);
+ expect(unit, isNotNull);
+ ConstantValueComputer computer = _makeConstantValueComputer();
+ computer.add(unit, source, source);
+ computer.computeValues();
+ assertErrors(source, expectedErrorCodes);
+ }
+
+ Map<String, DartObjectImpl> _assertType(
+ EvaluationResultImpl result, String typeName) {
+ expect(result.value, isNotNull);
+ DartObjectImpl value = result.value;
+ expect(value.type.displayName, typeName);
+ return value.fields;
+ }
+
+ bool _assertValidBool(EvaluationResultImpl result) {
+ expect(result.value, isNotNull);
+ DartObjectImpl value = result.value;
+ expect(value.type, typeProvider.boolType);
+ bool boolValue = value.boolValue;
+ expect(boolValue, isNotNull);
+ return boolValue;
+ }
+
+ int _assertValidInt(EvaluationResultImpl result) {
+ expect(result.value, isNotNull);
+ DartObjectImpl value = result.value;
+ expect(value.type, typeProvider.intType);
+ return value.intValue;
+ }
+
+ void _assertValidNull(EvaluationResultImpl result) {
+ expect(result.value, isNotNull);
+ DartObjectImpl value = result.value;
+ expect(value.type, typeProvider.nullType);
+ }
+
+ String _assertValidString(EvaluationResultImpl result) {
+ expect(result.value, isNotNull);
+ DartObjectImpl value = result.value;
+ expect(value.type, typeProvider.stringType);
+ return value.stringValue;
+ }
+
+ void _assertValidUnknown(EvaluationResultImpl result) {
+ expect(result.value, isNotNull);
+ DartObjectImpl value = result.value;
+ expect(value.isUnknown, isTrue);
+ }
+
+ EvaluationResultImpl _check_fromEnvironment_bool(
+ String valueInEnvironment, String defaultExpr) {
+ String envVarName = "x";
+ String varName = "foo";
+ if (valueInEnvironment != null) {
+ analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
+ }
+ String defaultArg =
+ defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
+ CompilationUnit compilationUnit = resolveSource(
+ "const $varName = const bool.fromEnvironment('$envVarName'$defaultArg);");
+ return _evaluateTopLevelVariable(compilationUnit, varName);
+ }
+
+ EvaluationResultImpl _check_fromEnvironment_int(
+ String valueInEnvironment, String defaultExpr) {
+ String envVarName = "x";
+ String varName = "foo";
+ if (valueInEnvironment != null) {
+ analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
+ }
+ String defaultArg =
+ defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
+ CompilationUnit compilationUnit = resolveSource(
+ "const $varName = const int.fromEnvironment('$envVarName'$defaultArg);");
+ return _evaluateTopLevelVariable(compilationUnit, varName);
+ }
+
+ EvaluationResultImpl _check_fromEnvironment_string(
+ String valueInEnvironment, String defaultExpr) {
+ String envVarName = "x";
+ String varName = "foo";
+ if (valueInEnvironment != null) {
+ analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
+ }
+ String defaultArg =
+ defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
+ CompilationUnit compilationUnit = resolveSource(
+ "const $varName = const String.fromEnvironment('$envVarName'$defaultArg);");
+ return _evaluateTopLevelVariable(compilationUnit, varName);
+ }
+
+ void _checkInstanceCreation_withSupertypeParams(bool isExplicit) {
+ String superCall = isExplicit ? " : super()" : "";
+ CompilationUnit compilationUnit = resolveSource("""
+class A<T> {
+ const A();
+}
+class B<T, U> extends A<T> {
+ const B()$superCall;
+}
+class C<T, U> extends A<U> {
+ const C()$superCall;
+}
+const b_int_num = const B<int, num>();
+const c_int_num = const C<int, num>();""");
+ EvaluationResultImpl b_int_num =
+ _evaluateTopLevelVariable(compilationUnit, "b_int_num");
+ Map<String, DartObjectImpl> b_int_num_fields =
+ _assertType(b_int_num, "B<int, num>");
+ _assertFieldType(b_int_num_fields, GenericState.SUPERCLASS_FIELD, "A<int>");
+ EvaluationResultImpl c_int_num =
+ _evaluateTopLevelVariable(compilationUnit, "c_int_num");
+ Map<String, DartObjectImpl> c_int_num_fields =
+ _assertType(c_int_num, "C<int, num>");
+ _assertFieldType(c_int_num_fields, GenericState.SUPERCLASS_FIELD, "A<num>");
+ }
+
+ void _checkInstanceCreationOptionalParams(
+ bool isFieldFormal, bool isNamed, bool hasDefault) {
+ String fieldName = "j";
+ String paramName = isFieldFormal ? fieldName : "i";
+ String formalParam =
+ "${isFieldFormal ? "this." : "int "}$paramName${hasDefault ? " = 3" : ""}";
+ CompilationUnit compilationUnit = resolveSource("""
+const x = const A();
+const y = const A(${isNamed ? '$paramName: ' : ''}10);
+class A {
+ const A(${isNamed ? "{$formalParam}" : "[$formalParam]"})${isFieldFormal ? "" : " : $fieldName = $paramName"};
+ final int $fieldName;
+}""");
+ EvaluationResultImpl x = _evaluateTopLevelVariable(compilationUnit, "x");
+ Map<String, DartObjectImpl> fieldsOfX = _assertType(x, "A");
+ expect(fieldsOfX, hasLength(1));
+ if (hasDefault) {
+ _assertIntField(fieldsOfX, fieldName, 3);
+ } else {
+ _assertNullField(fieldsOfX, fieldName);
+ }
+ EvaluationResultImpl y = _evaluateTopLevelVariable(compilationUnit, "y");
+ Map<String, DartObjectImpl> fieldsOfY = _assertType(y, "A");
+ expect(fieldsOfY, hasLength(1));
+ _assertIntField(fieldsOfY, fieldName, 10);
+ }
+
+ /**
+ * Search [compilationUnit] for a class named [className], containing a
+ * method [methodName], with exactly one annotation. Return the constant
+ * value of the annotation.
+ */
+ EvaluationResultImpl _evaluateAnnotation(
+ CompilationUnit compilationUnit, String className, String memberName) {
+ for (CompilationUnitMember member in compilationUnit.declarations) {
+ if (member is ClassDeclaration && member.name.name == className) {
+ for (ClassMember classMember in member.members) {
+ if (classMember is MethodDeclaration &&
+ classMember.name.name == memberName) {
+ expect(classMember.metadata, hasLength(1));
+ ElementAnnotationImpl elementAnnotation =
+ classMember.metadata[0].elementAnnotation;
+ return elementAnnotation.evaluationResult;
+ }
+ }
+ }
+ }
+ fail('Class member not found');
+ return null;
+ }
+
+ EvaluationResultImpl _evaluateTopLevelVariable(
+ CompilationUnit compilationUnit, String name) {
+ VariableDeclaration varDecl =
+ findTopLevelDeclaration(compilationUnit, name);
+ ConstTopLevelVariableElementImpl varElement = varDecl.element;
+ return varElement.evaluationResult;
+ }
+
+ ConstantValueComputer _makeConstantValueComputer() {
+ ConstantEvaluationValidator_ForTest validator =
+ new ConstantEvaluationValidator_ForTest();
+ validator.computer = new ConstantValueComputer(
+ analysisContext2,
+ analysisContext2.typeProvider,
+ analysisContext2.declaredVariables,
+ validator,
+ analysisContext2.typeSystem);
+ return validator.computer;
+ }
+
+ void _validate(bool shouldBeValid, VariableDeclarationList declarationList) {
+ for (VariableDeclaration declaration in declarationList.variables) {
+ VariableElementImpl element = declaration.element as VariableElementImpl;
+ expect(element, isNotNull);
+ EvaluationResultImpl result = element.evaluationResult;
+ if (shouldBeValid) {
+ expect(result.value, isNotNull);
+ } else {
+ expect(result.value, isNull);
+ }
+ }
+ }
+}
+
+@reflectiveTest
+class ConstantVisitorTest extends ResolverTestCase {
+ void test_visitConditionalExpression_false() {
+ Expression thenExpression = AstFactory.integer(1);
+ Expression elseExpression = AstFactory.integer(0);
+ ConditionalExpression expression = AstFactory.conditionalExpression(
+ AstFactory.booleanLiteral(false), thenExpression, elseExpression);
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ErrorReporter errorReporter =
+ new ErrorReporter(errorListener, _dummySource());
+ _assertValue(
+ 0,
+ expression.accept(new ConstantVisitor(
+ new ConstantEvaluationEngine(
+ new TestTypeProvider(), new DeclaredVariables(),
+ typeSystem: new TypeSystemImpl()),
+ errorReporter)));
+ errorListener.assertNoErrors();
+ }
+
+ void test_visitConditionalExpression_nonBooleanCondition() {
+ Expression thenExpression = AstFactory.integer(1);
+ Expression elseExpression = AstFactory.integer(0);
+ NullLiteral conditionExpression = AstFactory.nullLiteral();
+ ConditionalExpression expression = AstFactory.conditionalExpression(
+ conditionExpression, thenExpression, elseExpression);
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ErrorReporter errorReporter =
+ new ErrorReporter(errorListener, _dummySource());
+ DartObjectImpl result = expression.accept(new ConstantVisitor(
+ new ConstantEvaluationEngine(
+ new TestTypeProvider(), new DeclaredVariables(),
+ typeSystem: new TypeSystemImpl()),
+ errorReporter));
+ expect(result, isNull);
+ errorListener
+ .assertErrorsWithCodes([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
+ }
+
+ void test_visitConditionalExpression_nonConstantElse() {
+ Expression thenExpression = AstFactory.integer(1);
+ Expression elseExpression = AstFactory.identifier3("x");
+ ConditionalExpression expression = AstFactory.conditionalExpression(
+ AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ErrorReporter errorReporter =
+ new ErrorReporter(errorListener, _dummySource());
+ DartObjectImpl result = expression.accept(new ConstantVisitor(
+ new ConstantEvaluationEngine(
+ new TestTypeProvider(), new DeclaredVariables(),
+ typeSystem: new TypeSystemImpl()),
+ errorReporter));
+ expect(result, isNull);
+ errorListener
+ .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
+ }
+
+ void test_visitConditionalExpression_nonConstantThen() {
+ Expression thenExpression = AstFactory.identifier3("x");
+ Expression elseExpression = AstFactory.integer(0);
+ ConditionalExpression expression = AstFactory.conditionalExpression(
+ AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ErrorReporter errorReporter =
+ new ErrorReporter(errorListener, _dummySource());
+ DartObjectImpl result = expression.accept(new ConstantVisitor(
+ new ConstantEvaluationEngine(
+ new TestTypeProvider(), new DeclaredVariables(),
+ typeSystem: new TypeSystemImpl()),
+ errorReporter));
+ expect(result, isNull);
+ errorListener
+ .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
+ }
+
+ void test_visitConditionalExpression_true() {
+ Expression thenExpression = AstFactory.integer(1);
+ Expression elseExpression = AstFactory.integer(0);
+ ConditionalExpression expression = AstFactory.conditionalExpression(
+ AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ErrorReporter errorReporter =
+ new ErrorReporter(errorListener, _dummySource());
+ _assertValue(
+ 1,
+ expression.accept(new ConstantVisitor(
+ new ConstantEvaluationEngine(
+ new TestTypeProvider(), new DeclaredVariables(),
+ typeSystem: new TypeSystemImpl()),
+ errorReporter)));
+ errorListener.assertNoErrors();
+ }
+
+ void test_visitSimpleIdentifier_className() {
+ CompilationUnit compilationUnit = resolveSource('''
+const a = C;
+class C {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
+ expect(result.type, typeProvider.typeType);
+ ClassElement element = result.value;
+ expect(element.name, 'C');
+ }
+
+ void test_visitSimpleIdentifier_dynamic() {
+ CompilationUnit compilationUnit = resolveSource('''
+const a = dynamic;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
+ expect(result.type, typeProvider.typeType);
+ expect(result.value, typeProvider.dynamicType.element);
+ }
+
+ void test_visitSimpleIdentifier_inEnvironment() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const a = b;
+const b = 3;''');
+ Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
+ DartObjectImpl six =
+ new DartObjectImpl(typeProvider.intType, new IntState(6));
+ environment["b"] = six;
+ _assertValue(6, _evaluateConstant(compilationUnit, "a", environment));
+ }
+
+ void test_visitSimpleIdentifier_notInEnvironment() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const a = b;
+const b = 3;''');
+ Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
+ DartObjectImpl six =
+ new DartObjectImpl(typeProvider.intType, new IntState(6));
+ environment["c"] = six;
+ _assertValue(3, _evaluateConstant(compilationUnit, "a", environment));
+ }
+
+ void test_visitSimpleIdentifier_withoutEnvironment() {
+ CompilationUnit compilationUnit = resolveSource(r'''
+const a = b;
+const b = 3;''');
+ _assertValue(3, _evaluateConstant(compilationUnit, "a", null));
+ }
+
+ void _assertValue(int expectedValue, DartObjectImpl result) {
+ expect(result, isNotNull);
+ expect(result.type.name, "int");
+ expect(result.intValue, expectedValue);
+ }
+
+ NonExistingSource _dummySource() {
+ String path = '/test.dart';
+ return new NonExistingSource(path, toUri(path), UriKind.FILE_URI);
+ }
+
+ DartObjectImpl _evaluateConstant(CompilationUnit compilationUnit, String name,
+ Map<String, DartObjectImpl> lexicalEnvironment) {
+ Source source = compilationUnit.element.source;
+ Expression expression =
+ findTopLevelConstantExpression(compilationUnit, name);
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
+ DartObjectImpl result = expression.accept(new ConstantVisitor(
+ new ConstantEvaluationEngine(typeProvider, new DeclaredVariables(),
+ typeSystem: typeSystem),
+ errorReporter,
+ lexicalEnvironment: lexicalEnvironment));
+ errorListener.assertNoErrors();
+ return result;
+ }
+}
+
+@reflectiveTest
+class ContentCacheTest {
+ void test_setContents() {
+ Source source = new TestSource();
+ ContentCache cache = new ContentCache();
+ expect(cache.getContents(source), isNull);
+ expect(cache.getModificationStamp(source), isNull);
+ String contents = "library lib;";
+ expect(cache.setContents(source, contents), isNull);
+ expect(cache.getContents(source), contents);
+ expect(cache.getModificationStamp(source), isNotNull);
+ expect(cache.setContents(source, contents), contents);
+ expect(cache.setContents(source, null), contents);
+ expect(cache.getContents(source), isNull);
+ expect(cache.getModificationStamp(source), isNull);
+ expect(cache.setContents(source, null), isNull);
+ }
+}
+
+@reflectiveTest
+class CustomUriResolverTest {
+ void test_creation() {
+ expect(new CustomUriResolver({}), isNotNull);
+ }
+
+ void test_resolve_unknown_uri() {
+ UriResolver resolver =
+ new CustomUriResolver({'custom:library': '/path/to/library.dart',});
+ Source result =
+ resolver.resolveAbsolute(parseUriWithException("custom:non_library"));
+ expect(result, isNull);
+ }
+
+ void test_resolve_uri() {
+ String path =
+ FileUtilities2.createFile("/path/to/library.dart").getAbsolutePath();
+ UriResolver resolver = new CustomUriResolver({'custom:library': path,});
+ Source result =
+ resolver.resolveAbsolute(parseUriWithException("custom:library"));
+ expect(result, isNotNull);
+ expect(result.fullName, path);
+ }
+}
+
+@reflectiveTest
+class DartObjectImplTest extends EngineTestCase {
+ TypeProvider _typeProvider = new TestTypeProvider();
+
+ void test_add_knownDouble_knownDouble() {
+ _assertAdd(_doubleValue(3.0), _doubleValue(1.0), _doubleValue(2.0));
+ }
+
+ void test_add_knownDouble_knownInt() {
+ _assertAdd(_doubleValue(3.0), _doubleValue(1.0), _intValue(2));
+ }
+
+ void test_add_knownDouble_unknownDouble() {
+ _assertAdd(_doubleValue(null), _doubleValue(1.0), _doubleValue(null));
+ }
+
+ void test_add_knownDouble_unknownInt() {
+ _assertAdd(_doubleValue(null), _doubleValue(1.0), _intValue(null));
+ }
+
+ void test_add_knownInt_knownInt() {
+ _assertAdd(_intValue(3), _intValue(1), _intValue(2));
+ }
+
+ void test_add_knownInt_knownString() {
+ _assertAdd(null, _intValue(1), _stringValue("2"));
+ }
+
+ void test_add_knownInt_unknownDouble() {
+ _assertAdd(_doubleValue(null), _intValue(1), _doubleValue(null));
+ }
+
+ void test_add_knownInt_unknownInt() {
+ _assertAdd(_intValue(null), _intValue(1), _intValue(null));
+ }
+
+ void test_add_knownString_knownInt() {
+ _assertAdd(null, _stringValue("1"), _intValue(2));
+ }
+
+ void test_add_knownString_knownString() {
+ _assertAdd(_stringValue("ab"), _stringValue("a"), _stringValue("b"));
+ }
+
+ void test_add_knownString_unknownString() {
+ _assertAdd(_stringValue(null), _stringValue("a"), _stringValue(null));
+ }
+
+ void test_add_unknownDouble_knownDouble() {
+ _assertAdd(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
+ }
+
+ void test_add_unknownDouble_knownInt() {
+ _assertAdd(_doubleValue(null), _doubleValue(null), _intValue(2));
+ }
+
+ void test_add_unknownInt_knownDouble() {
+ _assertAdd(_doubleValue(null), _intValue(null), _doubleValue(2.0));
+ }
+
+ void test_add_unknownInt_knownInt() {
+ _assertAdd(_intValue(null), _intValue(null), _intValue(2));
+ }
+
+ void test_add_unknownString_knownString() {
+ _assertAdd(_stringValue(null), _stringValue(null), _stringValue("b"));
+ }
+
+ void test_add_unknownString_unknownString() {
+ _assertAdd(_stringValue(null), _stringValue(null), _stringValue(null));
+ }
+
+ void test_bitAnd_knownInt_knownInt() {
+ _assertBitAnd(_intValue(2), _intValue(6), _intValue(3));
+ }
+
+ void test_bitAnd_knownInt_knownString() {
+ _assertBitAnd(null, _intValue(6), _stringValue("3"));
+ }
+
+ void test_bitAnd_knownInt_unknownInt() {
+ _assertBitAnd(_intValue(null), _intValue(6), _intValue(null));
+ }
+
+ void test_bitAnd_knownString_knownInt() {
+ _assertBitAnd(null, _stringValue("6"), _intValue(3));
+ }
+
+ void test_bitAnd_unknownInt_knownInt() {
+ _assertBitAnd(_intValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_bitAnd_unknownInt_unknownInt() {
+ _assertBitAnd(_intValue(null), _intValue(null), _intValue(null));
+ }
+
+ void test_bitNot_knownInt() {
+ _assertBitNot(_intValue(-4), _intValue(3));
+ }
+
+ void test_bitNot_knownString() {
+ _assertBitNot(null, _stringValue("6"));
+ }
+
+ void test_bitNot_unknownInt() {
+ _assertBitNot(_intValue(null), _intValue(null));
+ }
+
+ void test_bitOr_knownInt_knownInt() {
+ _assertBitOr(_intValue(7), _intValue(6), _intValue(3));
+ }
+
+ void test_bitOr_knownInt_knownString() {
+ _assertBitOr(null, _intValue(6), _stringValue("3"));
+ }
+
+ void test_bitOr_knownInt_unknownInt() {
+ _assertBitOr(_intValue(null), _intValue(6), _intValue(null));
+ }
+
+ void test_bitOr_knownString_knownInt() {
+ _assertBitOr(null, _stringValue("6"), _intValue(3));
+ }
+
+ void test_bitOr_unknownInt_knownInt() {
+ _assertBitOr(_intValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_bitOr_unknownInt_unknownInt() {
+ _assertBitOr(_intValue(null), _intValue(null), _intValue(null));
+ }
+
+ void test_bitXor_knownInt_knownInt() {
+ _assertBitXor(_intValue(5), _intValue(6), _intValue(3));
+ }
+
+ void test_bitXor_knownInt_knownString() {
+ _assertBitXor(null, _intValue(6), _stringValue("3"));
+ }
+
+ void test_bitXor_knownInt_unknownInt() {
+ _assertBitXor(_intValue(null), _intValue(6), _intValue(null));
+ }
+
+ void test_bitXor_knownString_knownInt() {
+ _assertBitXor(null, _stringValue("6"), _intValue(3));
+ }
+
+ void test_bitXor_unknownInt_knownInt() {
+ _assertBitXor(_intValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_bitXor_unknownInt_unknownInt() {
+ _assertBitXor(_intValue(null), _intValue(null), _intValue(null));
+ }
+
+ void test_concatenate_knownInt_knownString() {
+ _assertConcatenate(null, _intValue(2), _stringValue("def"));
+ }
+
+ void test_concatenate_knownString_knownInt() {
+ _assertConcatenate(null, _stringValue("abc"), _intValue(3));
+ }
+
+ void test_concatenate_knownString_knownString() {
+ _assertConcatenate(
+ _stringValue("abcdef"), _stringValue("abc"), _stringValue("def"));
+ }
+
+ void test_concatenate_knownString_unknownString() {
+ _assertConcatenate(
+ _stringValue(null), _stringValue("abc"), _stringValue(null));
+ }
+
+ void test_concatenate_unknownString_knownString() {
+ _assertConcatenate(
+ _stringValue(null), _stringValue(null), _stringValue("def"));
+ }
+
+ void test_divide_knownDouble_knownDouble() {
+ _assertDivide(_doubleValue(3.0), _doubleValue(6.0), _doubleValue(2.0));
+ }
+
+ void test_divide_knownDouble_knownInt() {
+ _assertDivide(_doubleValue(3.0), _doubleValue(6.0), _intValue(2));
+ }
+
+ void test_divide_knownDouble_unknownDouble() {
+ _assertDivide(_doubleValue(null), _doubleValue(6.0), _doubleValue(null));
+ }
+
+ void test_divide_knownDouble_unknownInt() {
+ _assertDivide(_doubleValue(null), _doubleValue(6.0), _intValue(null));
+ }
+
+ void test_divide_knownInt_knownInt() {
+ _assertDivide(_doubleValue(3.0), _intValue(6), _intValue(2));
+ }
+
+ void test_divide_knownInt_knownString() {
+ _assertDivide(null, _intValue(6), _stringValue("2"));
+ }
+
+ void test_divide_knownInt_unknownDouble() {
+ _assertDivide(_doubleValue(null), _intValue(6), _doubleValue(null));
+ }
+
+ void test_divide_knownInt_unknownInt() {
+ _assertDivide(_doubleValue(null), _intValue(6), _intValue(null));
+ }
+
+ void test_divide_knownString_knownInt() {
+ _assertDivide(null, _stringValue("6"), _intValue(2));
+ }
+
+ void test_divide_unknownDouble_knownDouble() {
+ _assertDivide(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
+ }
+
+ void test_divide_unknownDouble_knownInt() {
+ _assertDivide(_doubleValue(null), _doubleValue(null), _intValue(2));
+ }
+
+ void test_divide_unknownInt_knownDouble() {
+ _assertDivide(_doubleValue(null), _intValue(null), _doubleValue(2.0));
+ }
+
+ void test_divide_unknownInt_knownInt() {
+ _assertDivide(_doubleValue(null), _intValue(null), _intValue(2));
+ }
+
+ void test_equalEqual_bool_false() {
+ _assertEqualEqual(_boolValue(false), _boolValue(false), _boolValue(true));
+ }
+
+ void test_equalEqual_bool_true() {
+ _assertEqualEqual(_boolValue(true), _boolValue(true), _boolValue(true));
+ }
+
+ void test_equalEqual_bool_unknown() {
+ _assertEqualEqual(_boolValue(null), _boolValue(null), _boolValue(false));
+ }
+
+ void test_equalEqual_double_false() {
+ _assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
+ }
+
+ void test_equalEqual_double_true() {
+ _assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
+ }
+
+ void test_equalEqual_double_unknown() {
+ _assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+ }
+
+ void test_equalEqual_int_false() {
+ _assertEqualEqual(_boolValue(false), _intValue(-5), _intValue(5));
+ }
+
+ void test_equalEqual_int_true() {
+ _assertEqualEqual(_boolValue(true), _intValue(5), _intValue(5));
+ }
+
+ void test_equalEqual_int_unknown() {
+ _assertEqualEqual(_boolValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_equalEqual_list_empty() {
+ _assertEqualEqual(null, _listValue(), _listValue());
+ }
+
+ void test_equalEqual_list_false() {
+ _assertEqualEqual(null, _listValue(), _listValue());
+ }
+
+ void test_equalEqual_map_empty() {
+ _assertEqualEqual(null, _mapValue(), _mapValue());
+ }
+
+ void test_equalEqual_map_false() {
+ _assertEqualEqual(null, _mapValue(), _mapValue());
+ }
+
+ void test_equalEqual_null() {
+ _assertEqualEqual(_boolValue(true), _nullValue(), _nullValue());
+ }
+
+ void test_equalEqual_string_false() {
+ _assertEqualEqual(
+ _boolValue(false), _stringValue("abc"), _stringValue("def"));
+ }
+
+ void test_equalEqual_string_true() {
+ _assertEqualEqual(
+ _boolValue(true), _stringValue("abc"), _stringValue("abc"));
+ }
+
+ void test_equalEqual_string_unknown() {
+ _assertEqualEqual(
+ _boolValue(null), _stringValue(null), _stringValue("def"));
+ }
+
+ void test_equals_list_false_differentSizes() {
+ expect(
+ _listValue([_boolValue(true)]) ==
+ _listValue([_boolValue(true), _boolValue(false)]),
+ isFalse);
+ }
+
+ void test_equals_list_false_sameSize() {
+ expect(_listValue([_boolValue(true)]) == _listValue([_boolValue(false)]),
+ isFalse);
+ }
+
+ void test_equals_list_true_empty() {
+ expect(_listValue(), _listValue());
+ }
+
+ void test_equals_list_true_nonEmpty() {
+ expect(_listValue([_boolValue(true)]), _listValue([_boolValue(true)]));
+ }
+
+ void test_equals_map_true_empty() {
+ expect(_mapValue(), _mapValue());
+ }
+
+ void test_equals_symbol_false() {
+ expect(_symbolValue("a") == _symbolValue("b"), isFalse);
+ }
+
+ void test_equals_symbol_true() {
+ expect(_symbolValue("a"), _symbolValue("a"));
+ }
+
+ void test_getValue_bool_false() {
+ expect(_boolValue(false).value, false);
+ }
+
+ void test_getValue_bool_true() {
+ expect(_boolValue(true).value, true);
+ }
+
+ void test_getValue_bool_unknown() {
+ expect(_boolValue(null).value, isNull);
+ }
+
+ void test_getValue_double_known() {
+ double value = 2.3;
+ expect(_doubleValue(value).value, value);
+ }
+
+ void test_getValue_double_unknown() {
+ expect(_doubleValue(null).value, isNull);
+ }
+
+ void test_getValue_int_known() {
+ int value = 23;
+ expect(_intValue(value).value, value);
+ }
+
+ void test_getValue_int_unknown() {
+ expect(_intValue(null).value, isNull);
+ }
+
+ void test_getValue_list_empty() {
+ Object result = _listValue().value;
+ _assertInstanceOfObjectArray(result);
+ List<Object> array = result as List<Object>;
+ expect(array, hasLength(0));
+ }
+
+ void test_getValue_list_valid() {
+ Object result = _listValue([_intValue(23)]).value;
+ _assertInstanceOfObjectArray(result);
+ List<Object> array = result as List<Object>;
+ expect(array, hasLength(1));
+ }
+
+ void test_getValue_map_empty() {
+ Object result = _mapValue().value;
+ EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
+ Map map = result as Map;
+ expect(map, hasLength(0));
+ }
+
+ void test_getValue_map_valid() {
+ Object result =
+ _mapValue([_stringValue("key"), _stringValue("value")]).value;
+ EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
+ Map map = result as Map;
+ expect(map, hasLength(1));
+ }
+
+ void test_getValue_null() {
+ expect(_nullValue().value, isNull);
+ }
+
+ void test_getValue_string_known() {
+ String value = "twenty-three";
+ expect(_stringValue(value).value, value);
+ }
+
+ void test_getValue_string_unknown() {
+ expect(_stringValue(null).value, isNull);
+ }
+
+ void test_greaterThan_knownDouble_knownDouble_false() {
+ _assertGreaterThan(_boolValue(false), _doubleValue(1.0), _doubleValue(2.0));
+ }
+
+ void test_greaterThan_knownDouble_knownDouble_true() {
+ _assertGreaterThan(_boolValue(true), _doubleValue(2.0), _doubleValue(1.0));
+ }
+
+ void test_greaterThan_knownDouble_knownInt_false() {
+ _assertGreaterThan(_boolValue(false), _doubleValue(1.0), _intValue(2));
+ }
+
+ void test_greaterThan_knownDouble_knownInt_true() {
+ _assertGreaterThan(_boolValue(true), _doubleValue(2.0), _intValue(1));
+ }
+
+ void test_greaterThan_knownDouble_unknownDouble() {
+ _assertGreaterThan(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+ }
+
+ void test_greaterThan_knownDouble_unknownInt() {
+ _assertGreaterThan(_boolValue(null), _doubleValue(1.0), _intValue(null));
+ }
+
+ void test_greaterThan_knownInt_knownInt_false() {
+ _assertGreaterThan(_boolValue(false), _intValue(1), _intValue(2));
+ }
+
+ void test_greaterThan_knownInt_knownInt_true() {
+ _assertGreaterThan(_boolValue(true), _intValue(2), _intValue(1));
+ }
+
+ void test_greaterThan_knownInt_knownString() {
+ _assertGreaterThan(null, _intValue(1), _stringValue("2"));
+ }
+
+ void test_greaterThan_knownInt_unknownDouble() {
+ _assertGreaterThan(_boolValue(null), _intValue(1), _doubleValue(null));
+ }
+
+ void test_greaterThan_knownInt_unknownInt() {
+ _assertGreaterThan(_boolValue(null), _intValue(1), _intValue(null));
+ }
+
+ void test_greaterThan_knownString_knownInt() {
+ _assertGreaterThan(null, _stringValue("1"), _intValue(2));
+ }
+
+ void test_greaterThan_unknownDouble_knownDouble() {
+ _assertGreaterThan(_boolValue(null), _doubleValue(null), _doubleValue(2.0));
+ }
+
+ void test_greaterThan_unknownDouble_knownInt() {
+ _assertGreaterThan(_boolValue(null), _doubleValue(null), _intValue(2));
+ }
+
+ void test_greaterThan_unknownInt_knownDouble() {
+ _assertGreaterThan(_boolValue(null), _intValue(null), _doubleValue(2.0));
+ }
+
+ void test_greaterThan_unknownInt_knownInt() {
+ _assertGreaterThan(_boolValue(null), _intValue(null), _intValue(2));
+ }
+
+ void test_greaterThanOrEqual_knownDouble_knownDouble_false() {
+ _assertGreaterThanOrEqual(
+ _boolValue(false), _doubleValue(1.0), _doubleValue(2.0));
+ }
+
+ void test_greaterThanOrEqual_knownDouble_knownDouble_true() {
+ _assertGreaterThanOrEqual(
+ _boolValue(true), _doubleValue(2.0), _doubleValue(1.0));
+ }
+
+ void test_greaterThanOrEqual_knownDouble_knownInt_false() {
+ _assertGreaterThanOrEqual(
+ _boolValue(false), _doubleValue(1.0), _intValue(2));
+ }
+
+ void test_greaterThanOrEqual_knownDouble_knownInt_true() {
+ _assertGreaterThanOrEqual(
+ _boolValue(true), _doubleValue(2.0), _intValue(1));
+ }
+
+ void test_greaterThanOrEqual_knownDouble_unknownDouble() {
+ _assertGreaterThanOrEqual(
+ _boolValue(null), _doubleValue(1.0), _doubleValue(null));
+ }
+
+ void test_greaterThanOrEqual_knownDouble_unknownInt() {
+ _assertGreaterThanOrEqual(
+ _boolValue(null), _doubleValue(1.0), _intValue(null));
+ }
+
+ void test_greaterThanOrEqual_knownInt_knownInt_false() {
+ _assertGreaterThanOrEqual(_boolValue(false), _intValue(1), _intValue(2));
+ }
+
+ void test_greaterThanOrEqual_knownInt_knownInt_true() {
+ _assertGreaterThanOrEqual(_boolValue(true), _intValue(2), _intValue(2));
+ }
+
+ void test_greaterThanOrEqual_knownInt_knownString() {
+ _assertGreaterThanOrEqual(null, _intValue(1), _stringValue("2"));
+ }
+
+ void test_greaterThanOrEqual_knownInt_unknownDouble() {
+ _assertGreaterThanOrEqual(
+ _boolValue(null), _intValue(1), _doubleValue(null));
+ }
+
+ void test_greaterThanOrEqual_knownInt_unknownInt() {
+ _assertGreaterThanOrEqual(_boolValue(null), _intValue(1), _intValue(null));
+ }
+
+ void test_greaterThanOrEqual_knownString_knownInt() {
+ _assertGreaterThanOrEqual(null, _stringValue("1"), _intValue(2));
+ }
+
+ void test_greaterThanOrEqual_unknownDouble_knownDouble() {
+ _assertGreaterThanOrEqual(
+ _boolValue(null), _doubleValue(null), _doubleValue(2.0));
+ }
+
+ void test_greaterThanOrEqual_unknownDouble_knownInt() {
+ _assertGreaterThanOrEqual(
+ _boolValue(null), _doubleValue(null), _intValue(2));
+ }
+
+ void test_greaterThanOrEqual_unknownInt_knownDouble() {
+ _assertGreaterThanOrEqual(
+ _boolValue(null), _intValue(null), _doubleValue(2.0));
+ }
+
+ void test_greaterThanOrEqual_unknownInt_knownInt() {
+ _assertGreaterThanOrEqual(_boolValue(null), _intValue(null), _intValue(2));
+ }
+
+ void test_hasExactValue_bool_false() {
+ expect(_boolValue(false).hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_bool_true() {
+ expect(_boolValue(true).hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_bool_unknown() {
+ expect(_boolValue(null).hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_double_known() {
+ expect(_doubleValue(2.3).hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_double_unknown() {
+ expect(_doubleValue(null).hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_dynamic() {
+ expect(_dynamicValue().hasExactValue, isFalse);
+ }
+
+ void test_hasExactValue_int_known() {
+ expect(_intValue(23).hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_int_unknown() {
+ expect(_intValue(null).hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_list_empty() {
+ expect(_listValue().hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_list_invalid() {
+ expect(_dynamicValue().hasExactValue, isFalse);
+ }
+
+ void test_hasExactValue_list_valid() {
+ expect(_listValue([_intValue(23)]).hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_map_empty() {
+ expect(_mapValue().hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_map_invalidKey() {
+ expect(_mapValue([_dynamicValue(), _stringValue("value")]).hasExactValue,
+ isFalse);
+ }
+
+ void test_hasExactValue_map_invalidValue() {
+ expect(_mapValue([_stringValue("key"), _dynamicValue()]).hasExactValue,
+ isFalse);
+ }
+
+ void test_hasExactValue_map_valid() {
+ expect(
+ _mapValue([_stringValue("key"), _stringValue("value")]).hasExactValue,
+ isTrue);
+ }
+
+ void test_hasExactValue_null() {
+ expect(_nullValue().hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_num() {
+ expect(_numValue().hasExactValue, isFalse);
+ }
+
+ void test_hasExactValue_string_known() {
+ expect(_stringValue("twenty-three").hasExactValue, isTrue);
+ }
+
+ void test_hasExactValue_string_unknown() {
+ expect(_stringValue(null).hasExactValue, isTrue);
+ }
+
+ void test_identical_bool_false() {
+ _assertIdentical(_boolValue(false), _boolValue(false), _boolValue(true));
+ }
+
+ void test_identical_bool_true() {
+ _assertIdentical(_boolValue(true), _boolValue(true), _boolValue(true));
+ }
+
+ void test_identical_bool_unknown() {
+ _assertIdentical(_boolValue(null), _boolValue(null), _boolValue(false));
+ }
+
+ void test_identical_double_false() {
+ _assertIdentical(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
+ }
+
+ void test_identical_double_true() {
+ _assertIdentical(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
+ }
+
+ void test_identical_double_unknown() {
+ _assertIdentical(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+ }
+
+ void test_identical_int_false() {
+ _assertIdentical(_boolValue(false), _intValue(-5), _intValue(5));
+ }
+
+ void test_identical_int_true() {
+ _assertIdentical(_boolValue(true), _intValue(5), _intValue(5));
+ }
+
+ void test_identical_int_unknown() {
+ _assertIdentical(_boolValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_identical_list_empty() {
+ _assertIdentical(_boolValue(true), _listValue(), _listValue());
+ }
+
+ void test_identical_list_false() {
+ _assertIdentical(
+ _boolValue(false), _listValue(), _listValue([_intValue(3)]));
+ }
+
+ void test_identical_map_empty() {
+ _assertIdentical(_boolValue(true), _mapValue(), _mapValue());
+ }
+
+ void test_identical_map_false() {
+ _assertIdentical(_boolValue(false), _mapValue(),
+ _mapValue([_intValue(1), _intValue(2)]));
+ }
+
+ void test_identical_null() {
+ _assertIdentical(_boolValue(true), _nullValue(), _nullValue());
+ }
+
+ void test_identical_string_false() {
+ _assertIdentical(
+ _boolValue(false), _stringValue("abc"), _stringValue("def"));
+ }
+
+ void test_identical_string_true() {
+ _assertIdentical(
+ _boolValue(true), _stringValue("abc"), _stringValue("abc"));
+ }
+
+ void test_identical_string_unknown() {
+ _assertIdentical(_boolValue(null), _stringValue(null), _stringValue("def"));
+ }
+
+ void test_integerDivide_knownDouble_knownDouble() {
+ _assertIntegerDivide(_intValue(3), _doubleValue(6.0), _doubleValue(2.0));
+ }
+
+ void test_integerDivide_knownDouble_knownInt() {
+ _assertIntegerDivide(_intValue(3), _doubleValue(6.0), _intValue(2));
+ }
+
+ void test_integerDivide_knownDouble_unknownDouble() {
+ _assertIntegerDivide(
+ _intValue(null), _doubleValue(6.0), _doubleValue(null));
+ }
+
+ void test_integerDivide_knownDouble_unknownInt() {
+ _assertIntegerDivide(_intValue(null), _doubleValue(6.0), _intValue(null));
+ }
+
+ void test_integerDivide_knownInt_knownInt() {
+ _assertIntegerDivide(_intValue(3), _intValue(6), _intValue(2));
+ }
+
+ void test_integerDivide_knownInt_knownString() {
+ _assertIntegerDivide(null, _intValue(6), _stringValue("2"));
+ }
+
+ void test_integerDivide_knownInt_unknownDouble() {
+ _assertIntegerDivide(_intValue(null), _intValue(6), _doubleValue(null));
+ }
+
+ void test_integerDivide_knownInt_unknownInt() {
+ _assertIntegerDivide(_intValue(null), _intValue(6), _intValue(null));
+ }
+
+ void test_integerDivide_knownString_knownInt() {
+ _assertIntegerDivide(null, _stringValue("6"), _intValue(2));
+ }
+
+ void test_integerDivide_unknownDouble_knownDouble() {
+ _assertIntegerDivide(
+ _intValue(null), _doubleValue(null), _doubleValue(2.0));
+ }
+
+ void test_integerDivide_unknownDouble_knownInt() {
+ _assertIntegerDivide(_intValue(null), _doubleValue(null), _intValue(2));
+ }
+
+ void test_integerDivide_unknownInt_knownDouble() {
+ _assertIntegerDivide(_intValue(null), _intValue(null), _doubleValue(2.0));
+ }
+
+ void test_integerDivide_unknownInt_knownInt() {
+ _assertIntegerDivide(_intValue(null), _intValue(null), _intValue(2));
+ }
+
+ void test_isBoolNumStringOrNull_bool_false() {
+ expect(_boolValue(false).isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_bool_true() {
+ expect(_boolValue(true).isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_bool_unknown() {
+ expect(_boolValue(null).isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_double_known() {
+ expect(_doubleValue(2.3).isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_double_unknown() {
+ expect(_doubleValue(null).isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_dynamic() {
+ expect(_dynamicValue().isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_int_known() {
+ expect(_intValue(23).isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_int_unknown() {
+ expect(_intValue(null).isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_list() {
+ expect(_listValue().isBoolNumStringOrNull, isFalse);
+ }
+
+ void test_isBoolNumStringOrNull_null() {
+ expect(_nullValue().isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_num() {
+ expect(_numValue().isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_string_known() {
+ expect(_stringValue("twenty-three").isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_isBoolNumStringOrNull_string_unknown() {
+ expect(_stringValue(null).isBoolNumStringOrNull, isTrue);
+ }
+
+ void test_lessThan_knownDouble_knownDouble_false() {
+ _assertLessThan(_boolValue(false), _doubleValue(2.0), _doubleValue(1.0));
+ }
+
+ void test_lessThan_knownDouble_knownDouble_true() {
+ _assertLessThan(_boolValue(true), _doubleValue(1.0), _doubleValue(2.0));
+ }
+
+ void test_lessThan_knownDouble_knownInt_false() {
+ _assertLessThan(_boolValue(false), _doubleValue(2.0), _intValue(1));
+ }
+
+ void test_lessThan_knownDouble_knownInt_true() {
+ _assertLessThan(_boolValue(true), _doubleValue(1.0), _intValue(2));
+ }
+
+ void test_lessThan_knownDouble_unknownDouble() {
+ _assertLessThan(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+ }
+
+ void test_lessThan_knownDouble_unknownInt() {
+ _assertLessThan(_boolValue(null), _doubleValue(1.0), _intValue(null));
+ }
+
+ void test_lessThan_knownInt_knownInt_false() {
+ _assertLessThan(_boolValue(false), _intValue(2), _intValue(1));
+ }
+
+ void test_lessThan_knownInt_knownInt_true() {
+ _assertLessThan(_boolValue(true), _intValue(1), _intValue(2));
+ }
+
+ void test_lessThan_knownInt_knownString() {
+ _assertLessThan(null, _intValue(1), _stringValue("2"));
+ }
+
+ void test_lessThan_knownInt_unknownDouble() {
+ _assertLessThan(_boolValue(null), _intValue(1), _doubleValue(null));
+ }
+
+ void test_lessThan_knownInt_unknownInt() {
+ _assertLessThan(_boolValue(null), _intValue(1), _intValue(null));
+ }
+
+ void test_lessThan_knownString_knownInt() {
+ _assertLessThan(null, _stringValue("1"), _intValue(2));
+ }
+
+ void test_lessThan_unknownDouble_knownDouble() {
+ _assertLessThan(_boolValue(null), _doubleValue(null), _doubleValue(2.0));
+ }
+
+ void test_lessThan_unknownDouble_knownInt() {
+ _assertLessThan(_boolValue(null), _doubleValue(null), _intValue(2));
+ }
+
+ void test_lessThan_unknownInt_knownDouble() {
+ _assertLessThan(_boolValue(null), _intValue(null), _doubleValue(2.0));
+ }
+
+ void test_lessThan_unknownInt_knownInt() {
+ _assertLessThan(_boolValue(null), _intValue(null), _intValue(2));
+ }
+
+ void test_lessThanOrEqual_knownDouble_knownDouble_false() {
+ _assertLessThanOrEqual(
+ _boolValue(false), _doubleValue(2.0), _doubleValue(1.0));
+ }
+
+ void test_lessThanOrEqual_knownDouble_knownDouble_true() {
+ _assertLessThanOrEqual(
+ _boolValue(true), _doubleValue(1.0), _doubleValue(2.0));
+ }
+
+ void test_lessThanOrEqual_knownDouble_knownInt_false() {
+ _assertLessThanOrEqual(_boolValue(false), _doubleValue(2.0), _intValue(1));
+ }
+
+ void test_lessThanOrEqual_knownDouble_knownInt_true() {
+ _assertLessThanOrEqual(_boolValue(true), _doubleValue(1.0), _intValue(2));
+ }
+
+ void test_lessThanOrEqual_knownDouble_unknownDouble() {
+ _assertLessThanOrEqual(
+ _boolValue(null), _doubleValue(1.0), _doubleValue(null));
+ }
+
+ void test_lessThanOrEqual_knownDouble_unknownInt() {
+ _assertLessThanOrEqual(
+ _boolValue(null), _doubleValue(1.0), _intValue(null));
+ }
+
+ void test_lessThanOrEqual_knownInt_knownInt_false() {
+ _assertLessThanOrEqual(_boolValue(false), _intValue(2), _intValue(1));
+ }
+
+ void test_lessThanOrEqual_knownInt_knownInt_true() {
+ _assertLessThanOrEqual(_boolValue(true), _intValue(1), _intValue(2));
+ }
+
+ void test_lessThanOrEqual_knownInt_knownString() {
+ _assertLessThanOrEqual(null, _intValue(1), _stringValue("2"));
+ }
+
+ void test_lessThanOrEqual_knownInt_unknownDouble() {
+ _assertLessThanOrEqual(_boolValue(null), _intValue(1), _doubleValue(null));
+ }
+
+ void test_lessThanOrEqual_knownInt_unknownInt() {
+ _assertLessThanOrEqual(_boolValue(null), _intValue(1), _intValue(null));
+ }
+
+ void test_lessThanOrEqual_knownString_knownInt() {
+ _assertLessThanOrEqual(null, _stringValue("1"), _intValue(2));
+ }
+
+ void test_lessThanOrEqual_unknownDouble_knownDouble() {
+ _assertLessThanOrEqual(
+ _boolValue(null), _doubleValue(null), _doubleValue(2.0));
+ }
+
+ void test_lessThanOrEqual_unknownDouble_knownInt() {
+ _assertLessThanOrEqual(_boolValue(null), _doubleValue(null), _intValue(2));
+ }
+
+ void test_lessThanOrEqual_unknownInt_knownDouble() {
+ _assertLessThanOrEqual(
+ _boolValue(null), _intValue(null), _doubleValue(2.0));
+ }
+
+ void test_lessThanOrEqual_unknownInt_knownInt() {
+ _assertLessThanOrEqual(_boolValue(null), _intValue(null), _intValue(2));
+ }
+
+ void test_logicalAnd_false_false() {
+ _assertLogicalAnd(_boolValue(false), _boolValue(false), _boolValue(false));
+ }
+
+ void test_logicalAnd_false_null() {
+ try {
+ _assertLogicalAnd(_boolValue(false), _boolValue(false), _nullValue());
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalAnd_false_string() {
+ try {
+ _assertLogicalAnd(
+ _boolValue(false), _boolValue(false), _stringValue("false"));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalAnd_false_true() {
+ _assertLogicalAnd(_boolValue(false), _boolValue(false), _boolValue(true));
+ }
+
+ void test_logicalAnd_null_false() {
+ try {
+ _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(false));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalAnd_null_true() {
+ try {
+ _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(true));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalAnd_string_false() {
+ try {
+ _assertLogicalAnd(
+ _boolValue(false), _stringValue("true"), _boolValue(false));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalAnd_string_true() {
+ try {
+ _assertLogicalAnd(
+ _boolValue(false), _stringValue("false"), _boolValue(true));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalAnd_true_false() {
+ _assertLogicalAnd(_boolValue(false), _boolValue(true), _boolValue(false));
+ }
+
+ void test_logicalAnd_true_null() {
+ _assertLogicalAnd(null, _boolValue(true), _nullValue());
+ }
+
+ void test_logicalAnd_true_string() {
+ try {
+ _assertLogicalAnd(
+ _boolValue(false), _boolValue(true), _stringValue("true"));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalAnd_true_true() {
+ _assertLogicalAnd(_boolValue(true), _boolValue(true), _boolValue(true));
+ }
+
+ void test_logicalNot_false() {
+ _assertLogicalNot(_boolValue(true), _boolValue(false));
+ }
+
+ void test_logicalNot_null() {
+ _assertLogicalNot(null, _nullValue());
+ }
+
+ void test_logicalNot_string() {
+ try {
+ _assertLogicalNot(_boolValue(true), _stringValue(null));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalNot_true() {
+ _assertLogicalNot(_boolValue(false), _boolValue(true));
+ }
+
+ void test_logicalNot_unknown() {
+ _assertLogicalNot(_boolValue(null), _boolValue(null));
+ }
+
+ void test_logicalOr_false_false() {
+ _assertLogicalOr(_boolValue(false), _boolValue(false), _boolValue(false));
+ }
+
+ void test_logicalOr_false_null() {
+ _assertLogicalOr(null, _boolValue(false), _nullValue());
+ }
+
+ void test_logicalOr_false_string() {
+ try {
+ _assertLogicalOr(
+ _boolValue(false), _boolValue(false), _stringValue("false"));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalOr_false_true() {
+ _assertLogicalOr(_boolValue(true), _boolValue(false), _boolValue(true));
+ }
+
+ void test_logicalOr_null_false() {
+ try {
+ _assertLogicalOr(_boolValue(false), _nullValue(), _boolValue(false));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalOr_null_true() {
+ try {
+ _assertLogicalOr(_boolValue(true), _nullValue(), _boolValue(true));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalOr_string_false() {
+ try {
+ _assertLogicalOr(
+ _boolValue(false), _stringValue("true"), _boolValue(false));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalOr_string_true() {
+ try {
+ _assertLogicalOr(
+ _boolValue(true), _stringValue("false"), _boolValue(true));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalOr_true_false() {
+ _assertLogicalOr(_boolValue(true), _boolValue(true), _boolValue(false));
+ }
+
+ void test_logicalOr_true_null() {
+ try {
+ _assertLogicalOr(_boolValue(true), _boolValue(true), _nullValue());
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalOr_true_string() {
+ try {
+ _assertLogicalOr(
+ _boolValue(true), _boolValue(true), _stringValue("true"));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_logicalOr_true_true() {
+ _assertLogicalOr(_boolValue(true), _boolValue(true), _boolValue(true));
+ }
+
+ void test_minus_knownDouble_knownDouble() {
+ _assertMinus(_doubleValue(1.0), _doubleValue(4.0), _doubleValue(3.0));
+ }
+
+ void test_minus_knownDouble_knownInt() {
+ _assertMinus(_doubleValue(1.0), _doubleValue(4.0), _intValue(3));
+ }
+
+ void test_minus_knownDouble_unknownDouble() {
+ _assertMinus(_doubleValue(null), _doubleValue(4.0), _doubleValue(null));
+ }
+
+ void test_minus_knownDouble_unknownInt() {
+ _assertMinus(_doubleValue(null), _doubleValue(4.0), _intValue(null));
+ }
+
+ void test_minus_knownInt_knownInt() {
+ _assertMinus(_intValue(1), _intValue(4), _intValue(3));
+ }
+
+ void test_minus_knownInt_knownString() {
+ _assertMinus(null, _intValue(4), _stringValue("3"));
+ }
+
+ void test_minus_knownInt_unknownDouble() {
+ _assertMinus(_doubleValue(null), _intValue(4), _doubleValue(null));
+ }
+
+ void test_minus_knownInt_unknownInt() {
+ _assertMinus(_intValue(null), _intValue(4), _intValue(null));
+ }
+
+ void test_minus_knownString_knownInt() {
+ _assertMinus(null, _stringValue("4"), _intValue(3));
+ }
+
+ void test_minus_unknownDouble_knownDouble() {
+ _assertMinus(_doubleValue(null), _doubleValue(null), _doubleValue(3.0));
+ }
+
+ void test_minus_unknownDouble_knownInt() {
+ _assertMinus(_doubleValue(null), _doubleValue(null), _intValue(3));
+ }
+
+ void test_minus_unknownInt_knownDouble() {
+ _assertMinus(_doubleValue(null), _intValue(null), _doubleValue(3.0));
+ }
+
+ void test_minus_unknownInt_knownInt() {
+ _assertMinus(_intValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_negated_double_known() {
+ _assertNegated(_doubleValue(2.0), _doubleValue(-2.0));
+ }
+
+ void test_negated_double_unknown() {
+ _assertNegated(_doubleValue(null), _doubleValue(null));
+ }
+
+ void test_negated_int_known() {
+ _assertNegated(_intValue(-3), _intValue(3));
+ }
+
+ void test_negated_int_unknown() {
+ _assertNegated(_intValue(null), _intValue(null));
+ }
+
+ void test_negated_string() {
+ _assertNegated(null, _stringValue(null));
+ }
+
+ void test_notEqual_bool_false() {
+ _assertNotEqual(_boolValue(false), _boolValue(true), _boolValue(true));
+ }
+
+ void test_notEqual_bool_true() {
+ _assertNotEqual(_boolValue(true), _boolValue(false), _boolValue(true));
+ }
+
+ void test_notEqual_bool_unknown() {
+ _assertNotEqual(_boolValue(null), _boolValue(null), _boolValue(false));
+ }
+
+ void test_notEqual_double_false() {
+ _assertNotEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(2.0));
+ }
+
+ void test_notEqual_double_true() {
+ _assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0));
+ }
+
+ void test_notEqual_double_unknown() {
+ _assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+ }
+
+ void test_notEqual_int_false() {
+ _assertNotEqual(_boolValue(false), _intValue(5), _intValue(5));
+ }
+
+ void test_notEqual_int_true() {
+ _assertNotEqual(_boolValue(true), _intValue(-5), _intValue(5));
+ }
+
+ void test_notEqual_int_unknown() {
+ _assertNotEqual(_boolValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_notEqual_null() {
+ _assertNotEqual(_boolValue(false), _nullValue(), _nullValue());
+ }
+
+ void test_notEqual_string_false() {
+ _assertNotEqual(
+ _boolValue(false), _stringValue("abc"), _stringValue("abc"));
+ }
+
+ void test_notEqual_string_true() {
+ _assertNotEqual(_boolValue(true), _stringValue("abc"), _stringValue("def"));
+ }
+
+ void test_notEqual_string_unknown() {
+ _assertNotEqual(_boolValue(null), _stringValue(null), _stringValue("def"));
+ }
+
+ void test_performToString_bool_false() {
+ _assertPerformToString(_stringValue("false"), _boolValue(false));
+ }
+
+ void test_performToString_bool_true() {
+ _assertPerformToString(_stringValue("true"), _boolValue(true));
+ }
+
+ void test_performToString_bool_unknown() {
+ _assertPerformToString(_stringValue(null), _boolValue(null));
+ }
+
+ void test_performToString_double_known() {
+ _assertPerformToString(_stringValue("2.0"), _doubleValue(2.0));
+ }
+
+ void test_performToString_double_unknown() {
+ _assertPerformToString(_stringValue(null), _doubleValue(null));
+ }
+
+ void test_performToString_int_known() {
+ _assertPerformToString(_stringValue("5"), _intValue(5));
+ }
+
+ void test_performToString_int_unknown() {
+ _assertPerformToString(_stringValue(null), _intValue(null));
+ }
+
+ void test_performToString_null() {
+ _assertPerformToString(_stringValue("null"), _nullValue());
+ }
+
+ void test_performToString_string_known() {
+ _assertPerformToString(_stringValue("abc"), _stringValue("abc"));
+ }
+
+ void test_performToString_string_unknown() {
+ _assertPerformToString(_stringValue(null), _stringValue(null));
+ }
+
+ void test_remainder_knownDouble_knownDouble() {
+ _assertRemainder(_doubleValue(1.0), _doubleValue(7.0), _doubleValue(2.0));
+ }
+
+ void test_remainder_knownDouble_knownInt() {
+ _assertRemainder(_doubleValue(1.0), _doubleValue(7.0), _intValue(2));
+ }
+
+ void test_remainder_knownDouble_unknownDouble() {
+ _assertRemainder(_doubleValue(null), _doubleValue(7.0), _doubleValue(null));
+ }
+
+ void test_remainder_knownDouble_unknownInt() {
+ _assertRemainder(_doubleValue(null), _doubleValue(6.0), _intValue(null));
+ }
+
+ void test_remainder_knownInt_knownInt() {
+ _assertRemainder(_intValue(1), _intValue(7), _intValue(2));
+ }
+
+ void test_remainder_knownInt_knownString() {
+ _assertRemainder(null, _intValue(7), _stringValue("2"));
+ }
+
+ void test_remainder_knownInt_unknownDouble() {
+ _assertRemainder(_doubleValue(null), _intValue(7), _doubleValue(null));
+ }
+
+ void test_remainder_knownInt_unknownInt() {
+ _assertRemainder(_intValue(null), _intValue(7), _intValue(null));
+ }
+
+ void test_remainder_knownString_knownInt() {
+ _assertRemainder(null, _stringValue("7"), _intValue(2));
+ }
+
+ void test_remainder_unknownDouble_knownDouble() {
+ _assertRemainder(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
+ }
+
+ void test_remainder_unknownDouble_knownInt() {
+ _assertRemainder(_doubleValue(null), _doubleValue(null), _intValue(2));
+ }
+
+ void test_remainder_unknownInt_knownDouble() {
+ _assertRemainder(_doubleValue(null), _intValue(null), _doubleValue(2.0));
+ }
+
+ void test_remainder_unknownInt_knownInt() {
+ _assertRemainder(_intValue(null), _intValue(null), _intValue(2));
+ }
+
+ void test_shiftLeft_knownInt_knownInt() {
+ _assertShiftLeft(_intValue(48), _intValue(6), _intValue(3));
+ }
+
+ void test_shiftLeft_knownInt_knownString() {
+ _assertShiftLeft(null, _intValue(6), _stringValue(null));
+ }
+
+ void test_shiftLeft_knownInt_tooLarge() {
+ _assertShiftLeft(
+ _intValue(null),
+ _intValue(6),
+ new DartObjectImpl(
+ _typeProvider.intType, new IntState(LONG_MAX_VALUE)));
+ }
+
+ void test_shiftLeft_knownInt_unknownInt() {
+ _assertShiftLeft(_intValue(null), _intValue(6), _intValue(null));
+ }
+
+ void test_shiftLeft_knownString_knownInt() {
+ _assertShiftLeft(null, _stringValue(null), _intValue(3));
+ }
+
+ void test_shiftLeft_unknownInt_knownInt() {
+ _assertShiftLeft(_intValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_shiftLeft_unknownInt_unknownInt() {
+ _assertShiftLeft(_intValue(null), _intValue(null), _intValue(null));
+ }
+
+ void test_shiftRight_knownInt_knownInt() {
+ _assertShiftRight(_intValue(6), _intValue(48), _intValue(3));
+ }
+
+ void test_shiftRight_knownInt_knownString() {
+ _assertShiftRight(null, _intValue(48), _stringValue(null));
+ }
+
+ void test_shiftRight_knownInt_tooLarge() {
+ _assertShiftRight(
+ _intValue(null),
+ _intValue(48),
+ new DartObjectImpl(
+ _typeProvider.intType, new IntState(LONG_MAX_VALUE)));
+ }
+
+ void test_shiftRight_knownInt_unknownInt() {
+ _assertShiftRight(_intValue(null), _intValue(48), _intValue(null));
+ }
+
+ void test_shiftRight_knownString_knownInt() {
+ _assertShiftRight(null, _stringValue(null), _intValue(3));
+ }
+
+ void test_shiftRight_unknownInt_knownInt() {
+ _assertShiftRight(_intValue(null), _intValue(null), _intValue(3));
+ }
+
+ void test_shiftRight_unknownInt_unknownInt() {
+ _assertShiftRight(_intValue(null), _intValue(null), _intValue(null));
+ }
+
+ void test_stringLength_int() {
+ try {
+ _assertStringLength(_intValue(null), _intValue(0));
+ fail("Expected EvaluationException");
+ } on EvaluationException {}
+ }
+
+ void test_stringLength_knownString() {
+ _assertStringLength(_intValue(3), _stringValue("abc"));
+ }
+
+ void test_stringLength_unknownString() {
+ _assertStringLength(_intValue(null), _stringValue(null));
+ }
+
+ void test_times_knownDouble_knownDouble() {
+ _assertTimes(_doubleValue(6.0), _doubleValue(2.0), _doubleValue(3.0));
+ }
+
+ void test_times_knownDouble_knownInt() {
+ _assertTimes(_doubleValue(6.0), _doubleValue(2.0), _intValue(3));
+ }
+
+ void test_times_knownDouble_unknownDouble() {
+ _assertTimes(_doubleValue(null), _doubleValue(2.0), _doubleValue(null));
+ }
+
+ void test_times_knownDouble_unknownInt() {
+ _assertTimes(_doubleValue(null), _doubleValue(2.0), _intValue(null));
+ }
+
+ void test_times_knownInt_knownInt() {
+ _assertTimes(_intValue(6), _intValue(2), _intValue(3));
+ }
+
+ void test_times_knownInt_knownString() {
+ _assertTimes(null, _intValue(2), _stringValue("3"));
+ }
+
+ void test_times_knownInt_unknownDouble() {
+ _assertTimes(_doubleValue(null), _intValue(2), _doubleValue(null));
+ }
+
+ void test_times_knownInt_unknownInt() {
+ _assertTimes(_intValue(null), _intValue(2), _intValue(null));
+ }
+
+ void test_times_knownString_knownInt() {
+ _assertTimes(null, _stringValue("2"), _intValue(3));
+ }
+
+ void test_times_unknownDouble_knownDouble() {
+ _assertTimes(_doubleValue(null), _doubleValue(null), _doubleValue(3.0));
+ }
+
+ void test_times_unknownDouble_knownInt() {
+ _assertTimes(_doubleValue(null), _doubleValue(null), _intValue(3));
+ }
+
+ void test_times_unknownInt_knownDouble() {
+ _assertTimes(_doubleValue(null), _intValue(null), _doubleValue(3.0));
+ }
+
+ void test_times_unknownInt_knownInt() {
+ _assertTimes(_intValue(null), _intValue(null), _intValue(3));
+ }
+
+ /**
+ * Assert that the result of adding the left and right operands is the expected value, or that the
+ * operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertAdd(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.add(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.add(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of bit-anding the left and right operands is the expected value, or that
+ * the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertBitAnd(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.bitAnd(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.bitAnd(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the bit-not of the operand is the expected value, or that the operation throws an
+ * exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param operand the operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertBitNot(DartObjectImpl expected, DartObjectImpl operand) {
+ if (expected == null) {
+ try {
+ operand.bitNot(_typeProvider);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = operand.bitNot(_typeProvider);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of bit-oring the left and right operands is the expected value, or that
+ * the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertBitOr(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.bitOr(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.bitOr(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of bit-xoring the left and right operands is the expected value, or that
+ * the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertBitXor(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.bitXor(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.bitXor(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of concatenating the left and right operands is the expected value, or
+ * that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertConcatenate(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.concatenate(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.concatenate(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of dividing the left and right operands is the expected value, or that
+ * the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertDivide(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.divide(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.divide(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of comparing the left and right operands for equality is the expected
+ * value, or that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertEqualEqual(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.equalEqual(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.equalEqual(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of comparing the left and right operands is the expected value, or that
+ * the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertGreaterThan(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.greaterThan(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.greaterThan(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of comparing the left and right operands is the expected value, or that
+ * the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertGreaterThanOrEqual(DartObjectImpl expected,
+ DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of comparing the left and right operands using
+ * identical() is the expected value.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ */
+ void _assertIdentical(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ DartObjectImpl result =
+ leftOperand.isIdentical(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+
+ void _assertInstanceOfObjectArray(Object result) {
+ // TODO(scheglov) implement
+ }
+
+ /**
+ * Assert that the result of dividing the left and right operands as integers is the expected
+ * value, or that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertIntegerDivide(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.integerDivide(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.integerDivide(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of comparing the left and right operands is the expected value, or that
+ * the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertLessThan(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.lessThan(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.lessThan(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of comparing the left and right operands is the expected value, or that
+ * the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertLessThanOrEqual(DartObjectImpl expected,
+ DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of logical-anding the left and right operands is the expected value, or
+ * that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertLogicalAnd(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.logicalAnd(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.logicalAnd(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the logical-not of the operand is the expected value, or that the operation throws
+ * an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param operand the operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertLogicalNot(DartObjectImpl expected, DartObjectImpl operand) {
+ if (expected == null) {
+ try {
+ operand.logicalNot(_typeProvider);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = operand.logicalNot(_typeProvider);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of logical-oring the left and right operands is the expected value, or
+ * that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertLogicalOr(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.logicalOr(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.logicalOr(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of subtracting the left and right operands is the expected value, or
+ * that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertMinus(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.minus(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.minus(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the negation of the operand is the expected value, or that the operation throws an
+ * exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param operand the operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertNegated(DartObjectImpl expected, DartObjectImpl operand) {
+ if (expected == null) {
+ try {
+ operand.negated(_typeProvider);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = operand.negated(_typeProvider);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of comparing the left and right operands for inequality is the expected
+ * value, or that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertNotEqual(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.notEqual(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.notEqual(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that converting the operand to a string is the expected value, or that the operation
+ * throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param operand the operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertPerformToString(DartObjectImpl expected, DartObjectImpl operand) {
+ if (expected == null) {
+ try {
+ operand.performToString(_typeProvider);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = operand.performToString(_typeProvider);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of taking the remainder of the left and right operands is the expected
+ * value, or that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertRemainder(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.remainder(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.remainder(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of multiplying the left and right operands is the expected value, or
+ * that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertShiftLeft(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.shiftLeft(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.shiftLeft(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of multiplying the left and right operands is the expected value, or
+ * that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertShiftRight(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.shiftRight(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result =
+ leftOperand.shiftRight(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the length of the operand is the expected value, or that the operation throws an
+ * exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param operand the operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertStringLength(DartObjectImpl expected, DartObjectImpl operand) {
+ if (expected == null) {
+ try {
+ operand.stringLength(_typeProvider);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = operand.stringLength(_typeProvider);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of multiplying the left and right operands is the expected value, or
+ * that the operation throws an exception if the expected value is `null`.
+ *
+ * @param expected the expected result of the operation
+ * @param leftOperand the left operand to the operation
+ * @param rightOperand the left operand to the operation
+ * @throws EvaluationException if the result is an exception when it should not be
+ */
+ void _assertTimes(DartObjectImpl expected, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand) {
+ if (expected == null) {
+ try {
+ leftOperand.times(_typeProvider, rightOperand);
+ fail("Expected an EvaluationException");
+ } on EvaluationException {}
+ } else {
+ DartObjectImpl result = leftOperand.times(_typeProvider, rightOperand);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ DartObjectImpl _boolValue(bool value) {
+ if (value == null) {
+ return new DartObjectImpl(
+ _typeProvider.boolType, BoolState.UNKNOWN_VALUE);
+ } else if (identical(value, false)) {
+ return new DartObjectImpl(_typeProvider.boolType, BoolState.FALSE_STATE);
+ } else if (identical(value, true)) {
+ return new DartObjectImpl(_typeProvider.boolType, BoolState.TRUE_STATE);
+ }
+ fail("Invalid boolean value used in test");
+ return null;
+ }
+
+ DartObjectImpl _doubleValue(double value) {
+ if (value == null) {
+ return new DartObjectImpl(
+ _typeProvider.doubleType, DoubleState.UNKNOWN_VALUE);
+ } else {
+ return new DartObjectImpl(
+ _typeProvider.doubleType, new DoubleState(value));
+ }
+ }
+
+ DartObjectImpl _dynamicValue() {
+ return new DartObjectImpl(
+ _typeProvider.nullType, DynamicState.DYNAMIC_STATE);
+ }
+
+ DartObjectImpl _intValue(int value) {
+ if (value == null) {
+ return new DartObjectImpl(_typeProvider.intType, IntState.UNKNOWN_VALUE);
+ } else {
+ return new DartObjectImpl(_typeProvider.intType, new IntState(value));
+ }
+ }
+
+ DartObjectImpl _listValue(
+ [List<DartObjectImpl> elements = DartObjectImpl.EMPTY_LIST]) {
+ return new DartObjectImpl(_typeProvider.listType, new ListState(elements));
+ }
+
+ DartObjectImpl _mapValue(
+ [List<DartObjectImpl> keyElementPairs = DartObjectImpl.EMPTY_LIST]) {
+ Map<DartObjectImpl, DartObjectImpl> map =
+ new Map<DartObjectImpl, DartObjectImpl>();
+ int count = keyElementPairs.length;
+ for (int i = 0; i < count;) {
+ map[keyElementPairs[i++]] = keyElementPairs[i++];
+ }
+ return new DartObjectImpl(_typeProvider.mapType, new MapState(map));
+ }
+
+ DartObjectImpl _nullValue() {
+ return new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
+ }
+
+ DartObjectImpl _numValue() {
+ return new DartObjectImpl(_typeProvider.nullType, NumState.UNKNOWN_VALUE);
+ }
+
+ DartObjectImpl _stringValue(String value) {
+ if (value == null) {
+ return new DartObjectImpl(
+ _typeProvider.stringType, StringState.UNKNOWN_VALUE);
+ } else {
+ return new DartObjectImpl(
+ _typeProvider.stringType, new StringState(value));
+ }
+ }
+
+ DartObjectImpl _symbolValue(String value) {
+ return new DartObjectImpl(_typeProvider.symbolType, new SymbolState(value));
+ }
+}
+
+@reflectiveTest
+class DartUriResolverTest {
+ void test_creation() {
+ JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
+ expect(sdkDirectory, isNotNull);
+ DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+ expect(new DartUriResolver(sdk), isNotNull);
+ }
+
+ void test_isDartUri_null_scheme() {
+ Uri uri = parseUriWithException("foo.dart");
+ expect('', uri.scheme);
+ expect(DartUriResolver.isDartUri(uri), isFalse);
+ }
+
+ void test_resolve_dart() {
+ JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
+ expect(sdkDirectory, isNotNull);
+ DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+ UriResolver resolver = new DartUriResolver(sdk);
+ Source result =
+ resolver.resolveAbsolute(parseUriWithException("dart:core"));
+ expect(result, isNotNull);
+ }
+
+ void test_resolve_dart_nonExistingLibrary() {
+ JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
+ expect(sdkDirectory, isNotNull);
+ DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+ UriResolver resolver = new DartUriResolver(sdk);
+ Source result = resolver.resolveAbsolute(parseUriWithException("dart:cor"));
+ expect(result, isNull);
+ }
+
+ void test_resolve_nonDart() {
+ JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
+ expect(sdkDirectory, isNotNull);
+ DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+ UriResolver resolver = new DartUriResolver(sdk);
+ Source result = resolver
+ .resolveAbsolute(parseUriWithException("package:some/file.dart"));
+ expect(result, isNull);
+ }
+}
+
+@reflectiveTest
+class DeclaredVariablesTest extends EngineTestCase {
+ void test_getBool_false() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ DeclaredVariables variables = new DeclaredVariables();
+ variables.define(variableName, "false");
+ DartObject object = variables.getBool(typeProvider, variableName);
+ expect(object, isNotNull);
+ expect(object.boolValue, false);
+ }
+
+ void test_getBool_invalid() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ DeclaredVariables variables = new DeclaredVariables();
+ variables.define(variableName, "not true");
+ _assertNullDartObject(
+ typeProvider, variables.getBool(typeProvider, variableName));
+ }
+
+ void test_getBool_true() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ DeclaredVariables variables = new DeclaredVariables();
+ variables.define(variableName, "true");
+ DartObject object = variables.getBool(typeProvider, variableName);
+ expect(object, isNotNull);
+ expect(object.boolValue, true);
+ }
+
+ void test_getBool_undefined() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ DeclaredVariables variables = new DeclaredVariables();
+ _assertUnknownDartObject(
+ typeProvider.boolType, variables.getBool(typeProvider, variableName));
+ }
+
+ void test_getInt_invalid() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ DeclaredVariables variables = new DeclaredVariables();
+ variables.define(variableName, "four score and seven years");
+ _assertNullDartObject(
+ typeProvider, variables.getInt(typeProvider, variableName));
+ }
+
+ void test_getInt_undefined() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ DeclaredVariables variables = new DeclaredVariables();
+ _assertUnknownDartObject(
+ typeProvider.intType, variables.getInt(typeProvider, variableName));
+ }
+
+ void test_getInt_valid() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ DeclaredVariables variables = new DeclaredVariables();
+ variables.define(variableName, "23");
+ DartObject object = variables.getInt(typeProvider, variableName);
+ expect(object, isNotNull);
+ expect(object.intValue, 23);
+ }
+
+ void test_getString_defined() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ String value = "value";
+ DeclaredVariables variables = new DeclaredVariables();
+ variables.define(variableName, value);
+ DartObject object = variables.getString(typeProvider, variableName);
+ expect(object, isNotNull);
+ expect(object.stringValue, value);
+ }
+
+ void test_getString_undefined() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ String variableName = "var";
+ DeclaredVariables variables = new DeclaredVariables();
+ _assertUnknownDartObject(typeProvider.stringType,
+ variables.getString(typeProvider, variableName));
+ }
+
+ void _assertNullDartObject(TestTypeProvider typeProvider, DartObject result) {
+ expect(result.type, typeProvider.nullType);
+ }
+
+ void _assertUnknownDartObject(
+ ParameterizedType expectedType, DartObject result) {
+ expect((result as DartObjectImpl).isUnknown, isTrue);
+ expect(result.type, expectedType);
+ }
+}
+
+@reflectiveTest
+class DirectoryBasedDartSdkTest {
+ void fail_getDocFileFor() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ JavaFile docFile = sdk.getDocFileFor("html");
+ expect(docFile, isNotNull);
+ }
+
+ void test_creation() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ expect(sdk, isNotNull);
+ }
+
+ void test_fromFile_invalid() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ expect(
+ sdk.fromFileUri(new JavaFile("/not/in/the/sdk.dart").toURI()), isNull);
+ }
+
+ void test_fromFile_library() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ Source source = sdk.fromFileUri(new JavaFile.relative(
+ new JavaFile.relative(sdk.libraryDirectory, "core"), "core.dart")
+ .toURI());
+ expect(source, isNotNull);
+ expect(source.isInSystemLibrary, isTrue);
+ expect(source.uri.toString(), "dart:core");
+ }
+
+ void test_fromFile_part() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ Source source = sdk.fromFileUri(new JavaFile.relative(
+ new JavaFile.relative(sdk.libraryDirectory, "core"), "num.dart")
+ .toURI());
+ expect(source, isNotNull);
+ expect(source.isInSystemLibrary, isTrue);
+ expect(source.uri.toString(), "dart:core/num.dart");
+ }
+
+ void test_getDart2JsExecutable() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ JavaFile executable = sdk.dart2JsExecutable;
+ expect(executable, isNotNull);
+ expect(executable.exists(), isTrue);
+ expect(executable.isExecutable(), isTrue);
+ }
+
+ void test_getDirectory() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ JavaFile directory = sdk.directory;
+ expect(directory, isNotNull);
+ expect(directory.exists(), isTrue);
+ }
+
+ void test_getDocDirectory() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ JavaFile directory = sdk.docDirectory;
+ expect(directory, isNotNull);
+ }
+
+ void test_getLibraryDirectory() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ JavaFile directory = sdk.libraryDirectory;
+ expect(directory, isNotNull);
+ expect(directory.exists(), isTrue);
+ }
+
+ void test_getPubExecutable() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ JavaFile executable = sdk.pubExecutable;
+ expect(executable, isNotNull);
+ expect(executable.exists(), isTrue);
+ expect(executable.isExecutable(), isTrue);
+ }
+
+ void test_getSdkVersion() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ String version = sdk.sdkVersion;
+ expect(version, isNotNull);
+ expect(version.length > 0, isTrue);
+ }
+
+ void test_getVmExecutable() {
+ DirectoryBasedDartSdk sdk = _createDartSdk();
+ JavaFile executable = sdk.vmExecutable;
+ expect(executable, isNotNull);
+ expect(executable.exists(), isTrue);
+ expect(executable.isExecutable(), isTrue);
+ }
+
+ DirectoryBasedDartSdk _createDartSdk() {
+ JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
+ expect(sdkDirectory, isNotNull,
+ reason:
+ "No SDK configured; set the property 'com.google.dart.sdk' on the command line");
+ return new DirectoryBasedDartSdk(sdkDirectory);
+ }
+}
+
+@reflectiveTest
+class DirectoryBasedSourceContainerTest {
+ void test_contains() {
+ JavaFile dir = FileUtilities2.createFile("/does/not/exist");
+ JavaFile file1 = FileUtilities2.createFile("/does/not/exist/some.dart");
+ JavaFile file2 =
+ FileUtilities2.createFile("/does/not/exist/folder/some2.dart");
+ JavaFile file3 = FileUtilities2.createFile("/does/not/exist3/some3.dart");
+ FileBasedSource source1 = new FileBasedSource(file1);
+ FileBasedSource source2 = new FileBasedSource(file2);
+ FileBasedSource source3 = new FileBasedSource(file3);
+ DirectoryBasedSourceContainer container =
+ new DirectoryBasedSourceContainer.con1(dir);
+ expect(container.contains(source1), isTrue);
+ expect(container.contains(source2), isTrue);
+ expect(container.contains(source3), isFalse);
+ }
+}
+
+@reflectiveTest
+class ElementBuilderTest extends EngineTestCase {
+ void test_visitCatchClause() {
+ // } catch (e, s) {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String exceptionParameterName = "e";
+ String stackParameterName = "s";
+ CatchClause clause =
+ AstFactory.catchClause2(exceptionParameterName, stackParameterName);
+ clause.accept(builder);
+
+ List<LocalVariableElement> variables = holder.localVariables;
+ expect(variables, hasLength(2));
+ VariableElement exceptionVariable = variables[0];
+ expect(exceptionVariable, isNotNull);
+ expect(exceptionVariable.name, exceptionParameterName);
+ expect(exceptionVariable.hasImplicitType, isTrue);
+ expect(exceptionVariable.isSynthetic, isFalse);
+ expect(exceptionVariable.isConst, isFalse);
+ expect(exceptionVariable.isFinal, isFalse);
+ expect(exceptionVariable.initializer, isNull);
+ VariableElement stackVariable = variables[1];
+ expect(stackVariable, isNotNull);
+ expect(stackVariable.name, stackParameterName);
+ expect(stackVariable.isSynthetic, isFalse);
+ expect(stackVariable.isConst, isFalse);
+ expect(stackVariable.isFinal, isFalse);
+ expect(stackVariable.initializer, isNull);
+ }
+
+ void test_visitCatchClause_withType() {
+ // } on E catch (e) {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String exceptionParameterName = "e";
+ CatchClause clause = AstFactory.catchClause4(
+ AstFactory.typeName4('E'), exceptionParameterName);
+ clause.accept(builder);
+
+ List<LocalVariableElement> variables = holder.localVariables;
+ expect(variables, hasLength(1));
+ VariableElement exceptionVariable = variables[0];
+ expect(exceptionVariable, isNotNull);
+ expect(exceptionVariable.name, exceptionParameterName);
+ expect(exceptionVariable.hasImplicitType, isFalse);
+ }
+
+ void test_visitClassDeclaration_abstract() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "C";
+ ClassDeclaration classDeclaration = AstFactory.classDeclaration(
+ Keyword.ABSTRACT, className, null, null, null, null);
+ classDeclaration.accept(builder);
+ List<ClassElement> types = holder.types;
+ expect(types, hasLength(1));
+ ClassElement type = types[0];
+ expect(type, isNotNull);
+ expect(type.name, className);
+ List<TypeParameterElement> typeParameters = type.typeParameters;
+ expect(typeParameters, hasLength(0));
+ expect(type.isAbstract, isTrue);
+ expect(type.isMixinApplication, isFalse);
+ expect(type.isSynthetic, isFalse);
+ }
+
+ void test_visitClassDeclaration_minimal() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "C";
+ ClassDeclaration classDeclaration =
+ AstFactory.classDeclaration(null, className, null, null, null, null);
+ classDeclaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ classDeclaration.accept(builder);
+ List<ClassElement> types = holder.types;
+ expect(types, hasLength(1));
+ ClassElement type = types[0];
+ expect(type, isNotNull);
+ expect(type.name, className);
+ List<TypeParameterElement> typeParameters = type.typeParameters;
+ expect(typeParameters, hasLength(0));
+ expect(type.isAbstract, isFalse);
+ expect(type.isMixinApplication, isFalse);
+ expect(type.isSynthetic, isFalse);
+ _assertHasDocRange(type, 50, 7);
+ }
+
+ void test_visitClassDeclaration_parameterized() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "C";
+ String firstVariableName = "E";
+ String secondVariableName = "F";
+ ClassDeclaration classDeclaration = AstFactory.classDeclaration(
+ null,
+ className,
+ AstFactory.typeParameterList([firstVariableName, secondVariableName]),
+ null,
+ null,
+ null);
+ classDeclaration.accept(builder);
+ List<ClassElement> types = holder.types;
+ expect(types, hasLength(1));
+ ClassElement type = types[0];
+ expect(type, isNotNull);
+ expect(type.name, className);
+ List<TypeParameterElement> typeParameters = type.typeParameters;
+ expect(typeParameters, hasLength(2));
+ expect(typeParameters[0].name, firstVariableName);
+ expect(typeParameters[1].name, secondVariableName);
+ expect(type.isAbstract, isFalse);
+ expect(type.isMixinApplication, isFalse);
+ expect(type.isSynthetic, isFalse);
+ }
+
+ void test_visitClassDeclaration_withMembers() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "C";
+ String typeParameterName = "E";
+ String fieldName = "f";
+ String methodName = "m";
+ ClassDeclaration classDeclaration = AstFactory.classDeclaration(
+ null,
+ className,
+ AstFactory.typeParameterList([typeParameterName]),
+ null,
+ null,
+ null, [
+ AstFactory.fieldDeclaration2(
+ false, null, [AstFactory.variableDeclaration(fieldName)]),
+ AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2())
+ ]);
+ classDeclaration.accept(builder);
+ List<ClassElement> types = holder.types;
+ expect(types, hasLength(1));
+ ClassElement type = types[0];
+ expect(type, isNotNull);
+ expect(type.name, className);
+ expect(type.isAbstract, isFalse);
+ expect(type.isMixinApplication, isFalse);
+ expect(type.isSynthetic, isFalse);
+ List<TypeParameterElement> typeParameters = type.typeParameters;
+ expect(typeParameters, hasLength(1));
+ TypeParameterElement typeParameter = typeParameters[0];
+ expect(typeParameter, isNotNull);
+ expect(typeParameter.name, typeParameterName);
+ List<FieldElement> fields = type.fields;
+ expect(fields, hasLength(1));
+ FieldElement field = fields[0];
+ expect(field, isNotNull);
+ expect(field.name, fieldName);
+ List<MethodElement> methods = type.methods;
+ expect(methods, hasLength(1));
+ MethodElement method = methods[0];
+ expect(method, isNotNull);
+ expect(method.name, methodName);
+ }
+
+ void test_visitClassTypeAlias() {
+ // class B {}
+ // class M {}
+ // class C = B with M
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ ClassElementImpl classB = ElementFactory.classElement2('B', []);
+ ConstructorElementImpl constructorB =
+ ElementFactory.constructorElement2(classB, '', []);
+ constructorB.setModifier(Modifier.SYNTHETIC, true);
+ classB.constructors = [constructorB];
+ ClassElement classM = ElementFactory.classElement2('M', []);
+ WithClause withClause =
+ AstFactory.withClause([AstFactory.typeName(classM, [])]);
+ ClassTypeAlias alias = AstFactory.classTypeAlias(
+ 'C', null, null, AstFactory.typeName(classB, []), withClause, null);
+ alias.accept(builder);
+ List<ClassElement> types = holder.types;
+ expect(types, hasLength(1));
+ ClassElement type = types[0];
+ expect(alias.element, same(type));
+ expect(type.name, equals('C'));
+ expect(type.isAbstract, isFalse);
+ expect(type.isMixinApplication, isTrue);
+ expect(type.isSynthetic, isFalse);
+ expect(type.typeParameters, isEmpty);
+ expect(type.fields, isEmpty);
+ expect(type.methods, isEmpty);
+ }
+
+ void test_visitClassTypeAlias_abstract() {
+ // class B {}
+ // class M {}
+ // abstract class C = B with M
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ ClassElementImpl classB = ElementFactory.classElement2('B', []);
+ ConstructorElementImpl constructorB =
+ ElementFactory.constructorElement2(classB, '', []);
+ constructorB.setModifier(Modifier.SYNTHETIC, true);
+ classB.constructors = [constructorB];
+ ClassElement classM = ElementFactory.classElement2('M', []);
+ WithClause withClause =
+ AstFactory.withClause([AstFactory.typeName(classM, [])]);
+ ClassTypeAlias classCAst = AstFactory.classTypeAlias('C', null,
+ Keyword.ABSTRACT, AstFactory.typeName(classB, []), withClause, null);
+ classCAst.accept(builder);
+ List<ClassElement> types = holder.types;
+ expect(types, hasLength(1));
+ ClassElement type = types[0];
+ expect(type.isAbstract, isTrue);
+ expect(type.isMixinApplication, isTrue);
+ }
+
+ void test_visitClassTypeAlias_typeParams() {
+ // class B {}
+ // class M {}
+ // class C<T> = B with M
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ ClassElementImpl classB = ElementFactory.classElement2('B', []);
+ ConstructorElementImpl constructorB =
+ ElementFactory.constructorElement2(classB, '', []);
+ constructorB.setModifier(Modifier.SYNTHETIC, true);
+ classB.constructors = [constructorB];
+ ClassElementImpl classM = ElementFactory.classElement2('M', []);
+ WithClause withClause =
+ AstFactory.withClause([AstFactory.typeName(classM, [])]);
+ ClassTypeAlias classCAst = AstFactory.classTypeAlias(
+ 'C',
+ AstFactory.typeParameterList(['T']),
+ null,
+ AstFactory.typeName(classB, []),
+ withClause,
+ null);
+ classCAst.accept(builder);
+ List<ClassElement> types = holder.types;
+ expect(types, hasLength(1));
+ ClassElement type = types[0];
+ expect(type.typeParameters, hasLength(1));
+ expect(type.typeParameters[0].name, equals('T'));
+ }
+
+ void test_visitConstructorDeclaration_external() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "A";
+ ConstructorDeclaration constructorDeclaration = AstFactory
+ .constructorDeclaration2(
+ null,
+ null,
+ AstFactory.identifier3(className),
+ null,
+ AstFactory.formalParameterList(),
+ null,
+ AstFactory.blockFunctionBody2());
+ constructorDeclaration.externalKeyword =
+ TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+ constructorDeclaration.accept(builder);
+ List<ConstructorElement> constructors = holder.constructors;
+ expect(constructors, hasLength(1));
+ ConstructorElement constructor = constructors[0];
+ expect(constructor, isNotNull);
+ expect(constructor.isExternal, isTrue);
+ expect(constructor.isFactory, isFalse);
+ expect(constructor.name, "");
+ expect(constructor.functions, hasLength(0));
+ expect(constructor.labels, hasLength(0));
+ expect(constructor.localVariables, hasLength(0));
+ expect(constructor.parameters, hasLength(0));
+ }
+
+ void test_visitConstructorDeclaration_factory() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "A";
+ ConstructorDeclaration constructorDeclaration = AstFactory
+ .constructorDeclaration2(
+ null,
+ Keyword.FACTORY,
+ AstFactory.identifier3(className),
+ null,
+ AstFactory.formalParameterList(),
+ null,
+ AstFactory.blockFunctionBody2());
+ constructorDeclaration.accept(builder);
+ List<ConstructorElement> constructors = holder.constructors;
+ expect(constructors, hasLength(1));
+ ConstructorElement constructor = constructors[0];
+ expect(constructor, isNotNull);
+ expect(constructor.isExternal, isFalse);
+ expect(constructor.isFactory, isTrue);
+ expect(constructor.name, "");
+ expect(constructor.functions, hasLength(0));
+ expect(constructor.labels, hasLength(0));
+ expect(constructor.localVariables, hasLength(0));
+ expect(constructor.parameters, hasLength(0));
+ }
+
+ void test_visitConstructorDeclaration_minimal() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "A";
+ ConstructorDeclaration constructorDeclaration = AstFactory
+ .constructorDeclaration2(
+ null,
+ null,
+ AstFactory.identifier3(className),
+ null,
+ AstFactory.formalParameterList(),
+ null,
+ AstFactory.blockFunctionBody2());
+ constructorDeclaration.documentationComment = AstFactory
+ .documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ constructorDeclaration.accept(builder);
+
+ List<ConstructorElement> constructors = holder.constructors;
+ expect(constructors, hasLength(1));
+ ConstructorElement constructor = constructors[0];
+ expect(constructor, isNotNull);
+ _assertHasDocRange(constructor, 50, 7);
+ expect(constructor.isExternal, isFalse);
+ expect(constructor.isFactory, isFalse);
+ expect(constructor.name, "");
+ expect(constructor.functions, hasLength(0));
+ expect(constructor.labels, hasLength(0));
+ expect(constructor.localVariables, hasLength(0));
+ expect(constructor.parameters, hasLength(0));
+ }
+
+ void test_visitConstructorDeclaration_named() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "A";
+ String constructorName = "c";
+ ConstructorDeclaration constructorDeclaration = AstFactory
+ .constructorDeclaration2(
+ null,
+ null,
+ AstFactory.identifier3(className),
+ constructorName,
+ AstFactory.formalParameterList(),
+ null,
+ AstFactory.blockFunctionBody2());
+ constructorDeclaration.accept(builder);
+ List<ConstructorElement> constructors = holder.constructors;
+ expect(constructors, hasLength(1));
+ ConstructorElement constructor = constructors[0];
+ expect(constructor, isNotNull);
+ expect(constructor.isExternal, isFalse);
+ expect(constructor.isFactory, isFalse);
+ expect(constructor.name, constructorName);
+ expect(constructor.functions, hasLength(0));
+ expect(constructor.labels, hasLength(0));
+ expect(constructor.localVariables, hasLength(0));
+ expect(constructor.parameters, hasLength(0));
+ expect(constructorDeclaration.name.staticElement, same(constructor));
+ expect(constructorDeclaration.element, same(constructor));
+ }
+
+ void test_visitConstructorDeclaration_unnamed() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String className = "A";
+ ConstructorDeclaration constructorDeclaration = AstFactory
+ .constructorDeclaration2(
+ null,
+ null,
+ AstFactory.identifier3(className),
+ null,
+ AstFactory.formalParameterList(),
+ null,
+ AstFactory.blockFunctionBody2());
+ constructorDeclaration.accept(builder);
+ List<ConstructorElement> constructors = holder.constructors;
+ expect(constructors, hasLength(1));
+ ConstructorElement constructor = constructors[0];
+ expect(constructor, isNotNull);
+ expect(constructor.isExternal, isFalse);
+ expect(constructor.isFactory, isFalse);
+ expect(constructor.name, "");
+ expect(constructor.functions, hasLength(0));
+ expect(constructor.labels, hasLength(0));
+ expect(constructor.localVariables, hasLength(0));
+ expect(constructor.parameters, hasLength(0));
+ expect(constructorDeclaration.element, same(constructor));
+ }
+
+ void test_visitDeclaredIdentifier_noType() {
+ // var i
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ var variableName = 'i';
+ DeclaredIdentifier identifier =
+ AstFactory.declaredIdentifier3(variableName);
+ AstFactory.forEachStatement(
+ identifier, AstFactory.nullLiteral(), AstFactory.emptyStatement());
+ identifier.accept(builder);
+
+ List<LocalVariableElement> variables = holder.localVariables;
+ expect(variables, hasLength(1));
+ LocalVariableElement variable = variables[0];
+ expect(variable, isNotNull);
+ expect(variable.hasImplicitType, isTrue);
+ expect(variable.isConst, isFalse);
+ expect(variable.isDeprecated, isFalse);
+ expect(variable.isFinal, isFalse);
+ expect(variable.isOverride, isFalse);
+ expect(variable.isPrivate, isFalse);
+ expect(variable.isPublic, isTrue);
+ expect(variable.isSynthetic, isFalse);
+ expect(variable.name, variableName);
+ }
+
+ void test_visitDeclaredIdentifier_type() {
+ // E i
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ var variableName = 'i';
+ DeclaredIdentifier identifier =
+ AstFactory.declaredIdentifier4(AstFactory.typeName4('E'), variableName);
+ AstFactory.forEachStatement(
+ identifier, AstFactory.nullLiteral(), AstFactory.emptyStatement());
+ identifier.accept(builder);
+
+ List<LocalVariableElement> variables = holder.localVariables;
+ expect(variables, hasLength(1));
+ LocalVariableElement variable = variables[0];
+ expect(variable, isNotNull);
+ expect(variable.hasImplicitType, isFalse);
+ expect(variable.isConst, isFalse);
+ expect(variable.isDeprecated, isFalse);
+ expect(variable.isFinal, isFalse);
+ expect(variable.isOverride, isFalse);
+ expect(variable.isPrivate, isFalse);
+ expect(variable.isPublic, isTrue);
+ expect(variable.isSynthetic, isFalse);
+ expect(variable.name, variableName);
+ }
+
+ void test_visitDefaultFormalParameter_noType() {
+ // p = 0
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = 'p';
+ DefaultFormalParameter formalParameter = AstFactory
+ .positionalFormalParameter(
+ AstFactory.simpleFormalParameter3(parameterName),
+ AstFactory.integer(0));
+ formalParameter.accept(builder);
+
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter.hasImplicitType, isTrue);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isDeprecated, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isInitializingFormal, isFalse);
+ expect(parameter.isOverride, isFalse);
+ expect(parameter.isPrivate, isFalse);
+ expect(parameter.isPublic, isTrue);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.name, parameterName);
+ }
+
+ void test_visitDefaultFormalParameter_type() {
+ // E p = 0
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = 'p';
+ DefaultFormalParameter formalParameter = AstFactory.namedFormalParameter(
+ AstFactory.simpleFormalParameter4(
+ AstFactory.typeName4('E'), parameterName),
+ AstFactory.integer(0));
+ formalParameter.accept(builder);
+
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter.hasImplicitType, isFalse);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isDeprecated, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isInitializingFormal, isFalse);
+ expect(parameter.isOverride, isFalse);
+ expect(parameter.isPrivate, isFalse);
+ expect(parameter.isPublic, isTrue);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.name, parameterName);
+ }
+
+ void test_visitEnumDeclaration() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String enumName = "E";
+ EnumDeclaration enumDeclaration =
+ AstFactory.enumDeclaration2(enumName, ["ONE"]);
+ enumDeclaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ enumDeclaration.accept(builder);
+ List<ClassElement> enums = holder.enums;
+ expect(enums, hasLength(1));
+ ClassElement enumElement = enums[0];
+ expect(enumElement, isNotNull);
+ _assertHasDocRange(enumElement, 50, 7);
+ expect(enumElement.name, enumName);
+ }
+
+ void test_visitFieldDeclaration() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String firstFieldName = "x";
+ String secondFieldName = "y";
+ FieldDeclaration fieldDeclaration =
+ AstFactory.fieldDeclaration2(false, null, [
+ AstFactory.variableDeclaration(firstFieldName),
+ AstFactory.variableDeclaration(secondFieldName)
+ ]);
+ fieldDeclaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ fieldDeclaration.accept(builder);
+
+ List<FieldElement> fields = holder.fields;
+ expect(fields, hasLength(2));
+
+ FieldElement firstField = fields[0];
+ expect(firstField, isNotNull);
+ _assertHasDocRange(firstField, 50, 7);
+ expect(firstField.name, firstFieldName);
+ expect(firstField.initializer, isNull);
+ expect(firstField.isConst, isFalse);
+ expect(firstField.isFinal, isFalse);
+ expect(firstField.isSynthetic, isFalse);
+
+ FieldElement secondField = fields[1];
+ expect(secondField, isNotNull);
+ _assertHasDocRange(secondField, 50, 7);
+ expect(secondField.name, secondFieldName);
+ expect(secondField.initializer, isNull);
+ expect(secondField.isConst, isFalse);
+ expect(secondField.isFinal, isFalse);
+ expect(secondField.isSynthetic, isFalse);
+ }
+
+ void test_visitFieldFormalParameter() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = "p";
+ FieldFormalParameter formalParameter =
+ AstFactory.fieldFormalParameter(null, null, parameterName);
+ formalParameter.accept(builder);
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter, isNotNull);
+ expect(parameter.name, parameterName);
+ expect(parameter.initializer, isNull);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.parameterKind, ParameterKind.REQUIRED);
+ expect(parameter.parameters, hasLength(0));
+ }
+
+ void test_visitFieldFormalParameter_funtionTyped() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = "p";
+ FieldFormalParameter formalParameter = AstFactory.fieldFormalParameter(
+ null,
+ null,
+ parameterName,
+ AstFactory
+ .formalParameterList([AstFactory.simpleFormalParameter3("a")]));
+ formalParameter.accept(builder);
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter, isNotNull);
+ expect(parameter.name, parameterName);
+ expect(parameter.initializer, isNull);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.parameterKind, ParameterKind.REQUIRED);
+ expect(parameter.parameters, hasLength(1));
+ }
+
+ void test_visitFormalParameterList() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String firstParameterName = "a";
+ String secondParameterName = "b";
+ FormalParameterList parameterList = AstFactory.formalParameterList([
+ AstFactory.simpleFormalParameter3(firstParameterName),
+ AstFactory.simpleFormalParameter3(secondParameterName)
+ ]);
+ parameterList.accept(builder);
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(2));
+ expect(parameters[0].name, firstParameterName);
+ expect(parameters[1].name, secondParameterName);
+ }
+
+ void test_visitFunctionDeclaration_external() {
+ // external f();
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String functionName = "f";
+ FunctionDeclaration declaration = AstFactory.functionDeclaration(
+ null,
+ null,
+ functionName,
+ AstFactory.functionExpression2(
+ AstFactory.formalParameterList(), AstFactory.emptyFunctionBody()));
+ declaration.externalKeyword =
+ TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+ declaration.accept(builder);
+
+ List<FunctionElement> functions = holder.functions;
+ expect(functions, hasLength(1));
+ FunctionElement function = functions[0];
+ expect(function, isNotNull);
+ expect(function.name, functionName);
+ expect(declaration.element, same(function));
+ expect(declaration.functionExpression.element, same(function));
+ expect(function.hasImplicitReturnType, isTrue);
+ expect(function.isExternal, isTrue);
+ expect(function.isSynthetic, isFalse);
+ expect(function.typeParameters, hasLength(0));
+ }
+
+ void test_visitFunctionDeclaration_getter() {
+ // get f() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String functionName = "f";
+ FunctionDeclaration declaration = AstFactory.functionDeclaration(
+ null,
+ Keyword.GET,
+ functionName,
+ AstFactory.functionExpression2(
+ AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
+ declaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ declaration.accept(builder);
+
+ List<PropertyAccessorElement> accessors = holder.accessors;
+ expect(accessors, hasLength(1));
+ PropertyAccessorElement accessor = accessors[0];
+ expect(accessor, isNotNull);
+ _assertHasDocRange(accessor, 50, 7);
+ expect(accessor.name, functionName);
+ expect(declaration.element, same(accessor));
+ expect(declaration.functionExpression.element, same(accessor));
+ expect(accessor.hasImplicitReturnType, isTrue);
+ expect(accessor.isGetter, isTrue);
+ expect(accessor.isExternal, isFalse);
+ expect(accessor.isSetter, isFalse);
+ expect(accessor.isSynthetic, isFalse);
+ expect(accessor.typeParameters, hasLength(0));
+ PropertyInducingElement variable = accessor.variable;
+ EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableElement,
+ TopLevelVariableElement, variable);
+ expect(variable.isSynthetic, isTrue);
+ }
+
+ void test_visitFunctionDeclaration_plain() {
+ // T f() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String functionName = "f";
+ FunctionDeclaration declaration = AstFactory.functionDeclaration(
+ AstFactory.typeName4('T'),
+ null,
+ functionName,
+ AstFactory.functionExpression2(
+ AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
+ declaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ declaration.accept(builder);
+
+ List<FunctionElement> functions = holder.functions;
+ expect(functions, hasLength(1));
+ FunctionElement function = functions[0];
+ expect(function, isNotNull);
+ _assertHasDocRange(function, 50, 7);
+ expect(function.hasImplicitReturnType, isFalse);
+ expect(function.name, functionName);
+ expect(declaration.element, same(function));
+ expect(declaration.functionExpression.element, same(function));
+ expect(function.isExternal, isFalse);
+ expect(function.isSynthetic, isFalse);
+ expect(function.typeParameters, hasLength(0));
+ }
+
+ void test_visitFunctionDeclaration_setter() {
+ // set f() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String functionName = "f";
+ FunctionDeclaration declaration = AstFactory.functionDeclaration(
+ null,
+ Keyword.SET,
+ functionName,
+ AstFactory.functionExpression2(
+ AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
+ declaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ declaration.accept(builder);
+
+ List<PropertyAccessorElement> accessors = holder.accessors;
+ expect(accessors, hasLength(1));
+ PropertyAccessorElement accessor = accessors[0];
+ expect(accessor, isNotNull);
+ _assertHasDocRange(accessor, 50, 7);
+ expect(accessor.hasImplicitReturnType, isFalse);
+ expect(accessor.name, "$functionName=");
+ expect(declaration.element, same(accessor));
+ expect(declaration.functionExpression.element, same(accessor));
+ expect(accessor.isGetter, isFalse);
+ expect(accessor.isExternal, isFalse);
+ expect(accessor.isSetter, isTrue);
+ expect(accessor.isSynthetic, isFalse);
+ expect(accessor.typeParameters, hasLength(0));
+ PropertyInducingElement variable = accessor.variable;
+ EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableElement,
+ TopLevelVariableElement, variable);
+ expect(variable.isSynthetic, isTrue);
+ }
+
+ void test_visitFunctionDeclaration_typeParameters() {
+ // f<E>() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String functionName = 'f';
+ String typeParameterName = 'E';
+ FunctionExpression expression = AstFactory.functionExpression3(
+ AstFactory.typeParameterList([typeParameterName]),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2());
+ FunctionDeclaration declaration =
+ AstFactory.functionDeclaration(null, null, functionName, expression);
+ declaration.accept(builder);
+
+ List<FunctionElement> functions = holder.functions;
+ expect(functions, hasLength(1));
+ FunctionElement function = functions[0];
+ expect(function, isNotNull);
+ expect(function.hasImplicitReturnType, isTrue);
+ expect(function.name, functionName);
+ expect(function.isExternal, isFalse);
+ expect(function.isSynthetic, isFalse);
+ expect(declaration.element, same(function));
+ expect(expression.element, same(function));
+ List<TypeParameterElement> typeParameters = function.typeParameters;
+ expect(typeParameters, hasLength(1));
+ TypeParameterElement typeParameter = typeParameters[0];
+ expect(typeParameter, isNotNull);
+ expect(typeParameter.name, typeParameterName);
+ }
+
+ void test_visitFunctionExpression() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ FunctionExpression expression = AstFactory.functionExpression2(
+ AstFactory.formalParameterList(), AstFactory.blockFunctionBody2());
+ expression.accept(builder);
+ List<FunctionElement> functions = holder.functions;
+ expect(functions, hasLength(1));
+ FunctionElement function = functions[0];
+ expect(function, isNotNull);
+ expect(expression.element, same(function));
+ expect(function.hasImplicitReturnType, isTrue);
+ expect(function.isSynthetic, isFalse);
+ expect(function.typeParameters, hasLength(0));
+ }
+
+ void test_visitFunctionTypeAlias() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String aliasName = "F";
+ String parameterName = "E";
+ FunctionTypeAlias aliasNode = AstFactory.typeAlias(
+ null, aliasName, AstFactory.typeParameterList([parameterName]), null);
+ aliasNode.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ aliasNode.accept(builder);
+
+ List<FunctionTypeAliasElement> aliases = holder.typeAliases;
+ expect(aliases, hasLength(1));
+ FunctionTypeAliasElement alias = aliases[0];
+ expect(alias, isNotNull);
+ _assertHasDocRange(alias, 50, 7);
+ expect(alias.name, aliasName);
+ expect(alias.parameters, hasLength(0));
+ List<TypeParameterElement> typeParameters = alias.typeParameters;
+ expect(typeParameters, hasLength(1));
+ TypeParameterElement typeParameter = typeParameters[0];
+ expect(typeParameter, isNotNull);
+ expect(typeParameter.name, parameterName);
+ }
+
+ void test_visitFunctionTypedFormalParameter() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = "p";
+ FunctionTypedFormalParameter formalParameter =
+ AstFactory.functionTypedFormalParameter(null, parameterName);
+ _useParameterInMethod(formalParameter, 100, 110);
+ formalParameter.accept(builder);
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter, isNotNull);
+ expect(parameter.name, parameterName);
+ expect(parameter.initializer, isNull);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.parameterKind, ParameterKind.REQUIRED);
+ SourceRange visibleRange = parameter.visibleRange;
+ expect(100, visibleRange.offset);
+ expect(110, visibleRange.end);
+ }
+
+ void test_visitFunctionTypedFormalParameter_withTypeParameters() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = "p";
+ FunctionTypedFormalParameter formalParameter =
+ AstFactory.functionTypedFormalParameter(null, parameterName);
+ formalParameter.typeParameters = AstFactory.typeParameterList(['F']);
+ _useParameterInMethod(formalParameter, 100, 110);
+ formalParameter.accept(builder);
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter, isNotNull);
+ expect(parameter.name, parameterName);
+ expect(parameter.initializer, isNull);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.parameterKind, ParameterKind.REQUIRED);
+ expect(parameter.typeParameters, hasLength(1));
+ SourceRange visibleRange = parameter.visibleRange;
+ expect(100, visibleRange.offset);
+ expect(110, visibleRange.end);
+ }
+
+ void test_visitLabeledStatement() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String labelName = "l";
+ LabeledStatement statement = AstFactory.labeledStatement(
+ [AstFactory.label2(labelName)], AstFactory.breakStatement());
+ statement.accept(builder);
+ List<LabelElement> labels = holder.labels;
+ expect(labels, hasLength(1));
+ LabelElement label = labels[0];
+ expect(label, isNotNull);
+ expect(label.name, labelName);
+ expect(label.isSynthetic, isFalse);
+ }
+
+ void test_visitMethodDeclaration_abstract() {
+ // m();
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.emptyFunctionBody());
+ methodDeclaration.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ MethodElement method = methods[0];
+ expect(method, isNotNull);
+ expect(method.hasImplicitReturnType, isTrue);
+ expect(method.name, methodName);
+ expect(method.functions, hasLength(0));
+ expect(method.labels, hasLength(0));
+ expect(method.localVariables, hasLength(0));
+ expect(method.parameters, hasLength(0));
+ expect(method.typeParameters, hasLength(0));
+ expect(method.isAbstract, isTrue);
+ expect(method.isExternal, isFalse);
+ expect(method.isStatic, isFalse);
+ expect(method.isSynthetic, isFalse);
+ }
+
+ void test_visitMethodDeclaration_external() {
+ // external m();
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.emptyFunctionBody());
+ methodDeclaration.externalKeyword =
+ TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+ methodDeclaration.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ MethodElement method = methods[0];
+ expect(method, isNotNull);
+ expect(method.hasImplicitReturnType, isTrue);
+ expect(method.name, methodName);
+ expect(method.functions, hasLength(0));
+ expect(method.labels, hasLength(0));
+ expect(method.localVariables, hasLength(0));
+ expect(method.parameters, hasLength(0));
+ expect(method.typeParameters, hasLength(0));
+ expect(method.isAbstract, isFalse);
+ expect(method.isExternal, isTrue);
+ expect(method.isStatic, isFalse);
+ expect(method.isSynthetic, isFalse);
+ }
+
+ void test_visitMethodDeclaration_getter() {
+ // get m() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ Keyword.GET,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2());
+ methodDeclaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ methodDeclaration.accept(builder);
+
+ List<FieldElement> fields = holder.fields;
+ expect(fields, hasLength(1));
+ FieldElement field = fields[0];
+ expect(field, isNotNull);
+ expect(field.name, methodName);
+ expect(field.isSynthetic, isTrue);
+ expect(field.setter, isNull);
+ PropertyAccessorElement getter = field.getter;
+ expect(getter, isNotNull);
+ _assertHasDocRange(getter, 50, 7);
+ expect(getter.hasImplicitReturnType, isTrue);
+ expect(getter.isAbstract, isFalse);
+ expect(getter.isExternal, isFalse);
+ expect(getter.isGetter, isTrue);
+ expect(getter.isSynthetic, isFalse);
+ expect(getter.name, methodName);
+ expect(getter.variable, field);
+ expect(getter.functions, hasLength(0));
+ expect(getter.labels, hasLength(0));
+ expect(getter.localVariables, hasLength(0));
+ expect(getter.parameters, hasLength(0));
+ }
+
+ void test_visitMethodDeclaration_getter_abstract() {
+ // get m();
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ Keyword.GET,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.emptyFunctionBody());
+ methodDeclaration.accept(builder);
+
+ List<FieldElement> fields = holder.fields;
+ expect(fields, hasLength(1));
+ FieldElement field = fields[0];
+ expect(field, isNotNull);
+ expect(field.name, methodName);
+ expect(field.isSynthetic, isTrue);
+ expect(field.setter, isNull);
+ PropertyAccessorElement getter = field.getter;
+ expect(getter, isNotNull);
+ expect(getter.hasImplicitReturnType, isTrue);
+ expect(getter.isAbstract, isTrue);
+ expect(getter.isExternal, isFalse);
+ expect(getter.isGetter, isTrue);
+ expect(getter.isSynthetic, isFalse);
+ expect(getter.name, methodName);
+ expect(getter.variable, field);
+ expect(getter.functions, hasLength(0));
+ expect(getter.labels, hasLength(0));
+ expect(getter.localVariables, hasLength(0));
+ expect(getter.parameters, hasLength(0));
+ }
+
+ void test_visitMethodDeclaration_getter_external() {
+ // external get m();
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration(
+ null,
+ null,
+ Keyword.GET,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList());
+ methodDeclaration.externalKeyword =
+ TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+ methodDeclaration.accept(builder);
+
+ List<FieldElement> fields = holder.fields;
+ expect(fields, hasLength(1));
+ FieldElement field = fields[0];
+ expect(field, isNotNull);
+ expect(field.name, methodName);
+ expect(field.isSynthetic, isTrue);
+ expect(field.setter, isNull);
+ PropertyAccessorElement getter = field.getter;
+ expect(getter, isNotNull);
+ expect(getter.hasImplicitReturnType, isTrue);
+ expect(getter.isAbstract, isFalse);
+ expect(getter.isExternal, isTrue);
+ expect(getter.isGetter, isTrue);
+ expect(getter.isSynthetic, isFalse);
+ expect(getter.name, methodName);
+ expect(getter.variable, field);
+ expect(getter.functions, hasLength(0));
+ expect(getter.labels, hasLength(0));
+ expect(getter.localVariables, hasLength(0));
+ expect(getter.parameters, hasLength(0));
+ }
+
+ void test_visitMethodDeclaration_minimal() {
+ // T m() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ AstFactory.typeName4('T'),
+ null,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2());
+ methodDeclaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ methodDeclaration.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ MethodElement method = methods[0];
+ expect(method, isNotNull);
+ _assertHasDocRange(method, 50, 7);
+ expect(method.hasImplicitReturnType, isFalse);
+ expect(method.name, methodName);
+ expect(method.functions, hasLength(0));
+ expect(method.labels, hasLength(0));
+ expect(method.localVariables, hasLength(0));
+ expect(method.parameters, hasLength(0));
+ expect(method.typeParameters, hasLength(0));
+ expect(method.isAbstract, isFalse);
+ expect(method.isExternal, isFalse);
+ expect(method.isStatic, isFalse);
+ expect(method.isSynthetic, isFalse);
+ }
+
+ void test_visitMethodDeclaration_operator() {
+ // operator +(addend) {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "+";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ Keyword.OPERATOR,
+ AstFactory.identifier3(methodName),
+ AstFactory
+ .formalParameterList([AstFactory.simpleFormalParameter3("addend")]),
+ AstFactory.blockFunctionBody2());
+ methodDeclaration.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ MethodElement method = methods[0];
+ expect(method, isNotNull);
+ expect(method.hasImplicitReturnType, isTrue);
+ expect(method.name, methodName);
+ expect(method.functions, hasLength(0));
+ expect(method.labels, hasLength(0));
+ expect(method.localVariables, hasLength(0));
+ expect(method.parameters, hasLength(1));
+ expect(method.typeParameters, hasLength(0));
+ expect(method.isAbstract, isFalse);
+ expect(method.isExternal, isFalse);
+ expect(method.isStatic, isFalse);
+ expect(method.isSynthetic, isFalse);
+ }
+
+ void test_visitMethodDeclaration_setter() {
+ // set m() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ Keyword.SET,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2());
+ methodDeclaration.documentationComment = AstFactory.documentationComment(
+ [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+ methodDeclaration.accept(builder);
+
+ List<FieldElement> fields = holder.fields;
+ expect(fields, hasLength(1));
+ FieldElement field = fields[0];
+ expect(field, isNotNull);
+ expect(field.name, methodName);
+ expect(field.isSynthetic, isTrue);
+ expect(field.getter, isNull);
+
+ PropertyAccessorElement setter = field.setter;
+ expect(setter, isNotNull);
+ _assertHasDocRange(setter, 50, 7);
+ expect(setter.hasImplicitReturnType, isFalse);
+ expect(setter.isAbstract, isFalse);
+ expect(setter.isExternal, isFalse);
+ expect(setter.isSetter, isTrue);
+ expect(setter.isSynthetic, isFalse);
+ expect(setter.name, "$methodName=");
+ expect(setter.displayName, methodName);
+ expect(setter.variable, field);
+ expect(setter.functions, hasLength(0));
+ expect(setter.labels, hasLength(0));
+ expect(setter.localVariables, hasLength(0));
+ expect(setter.parameters, hasLength(0));
+ }
+
+ void test_visitMethodDeclaration_setter_abstract() {
+ // set m();
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ Keyword.SET,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.emptyFunctionBody());
+ methodDeclaration.accept(builder);
+
+ List<FieldElement> fields = holder.fields;
+ expect(fields, hasLength(1));
+ FieldElement field = fields[0];
+ expect(field, isNotNull);
+ expect(field.name, methodName);
+ expect(field.isSynthetic, isTrue);
+ expect(field.getter, isNull);
+ PropertyAccessorElement setter = field.setter;
+ expect(setter, isNotNull);
+ expect(setter.hasImplicitReturnType, isFalse);
+ expect(setter.isAbstract, isTrue);
+ expect(setter.isExternal, isFalse);
+ expect(setter.isSetter, isTrue);
+ expect(setter.isSynthetic, isFalse);
+ expect(setter.name, "$methodName=");
+ expect(setter.displayName, methodName);
+ expect(setter.variable, field);
+ expect(setter.functions, hasLength(0));
+ expect(setter.labels, hasLength(0));
+ expect(setter.localVariables, hasLength(0));
+ expect(setter.parameters, hasLength(0));
+ }
+
+ void test_visitMethodDeclaration_setter_external() {
+ // external m();
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration(
+ null,
+ null,
+ Keyword.SET,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList());
+ methodDeclaration.externalKeyword =
+ TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+ methodDeclaration.accept(builder);
+
+ List<FieldElement> fields = holder.fields;
+ expect(fields, hasLength(1));
+ FieldElement field = fields[0];
+ expect(field, isNotNull);
+ expect(field.name, methodName);
+ expect(field.isSynthetic, isTrue);
+ expect(field.getter, isNull);
+ PropertyAccessorElement setter = field.setter;
+ expect(setter, isNotNull);
+ expect(setter.hasImplicitReturnType, isFalse);
+ expect(setter.isAbstract, isFalse);
+ expect(setter.isExternal, isTrue);
+ expect(setter.isSetter, isTrue);
+ expect(setter.isSynthetic, isFalse);
+ expect(setter.name, "$methodName=");
+ expect(setter.displayName, methodName);
+ expect(setter.variable, field);
+ expect(setter.functions, hasLength(0));
+ expect(setter.labels, hasLength(0));
+ expect(setter.localVariables, hasLength(0));
+ expect(setter.parameters, hasLength(0));
+ }
+
+ void test_visitMethodDeclaration_static() {
+ // static m() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ Keyword.STATIC,
+ null,
+ null,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2());
+ methodDeclaration.accept(builder);
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ MethodElement method = methods[0];
+ expect(method, isNotNull);
+ expect(method.hasImplicitReturnType, isTrue);
+ expect(method.name, methodName);
+ expect(method.functions, hasLength(0));
+ expect(method.labels, hasLength(0));
+ expect(method.localVariables, hasLength(0));
+ expect(method.parameters, hasLength(0));
+ expect(method.typeParameters, hasLength(0));
+ expect(method.isAbstract, isFalse);
+ expect(method.isExternal, isFalse);
+ expect(method.isStatic, isTrue);
+ expect(method.isSynthetic, isFalse);
+ }
+
+ void test_visitMethodDeclaration_typeParameters() {
+ // m<E>() {}
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2());
+ methodDeclaration.typeParameters = AstFactory.typeParameterList(['E']);
+ methodDeclaration.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ MethodElement method = methods[0];
+ expect(method, isNotNull);
+ expect(method.hasImplicitReturnType, isTrue);
+ expect(method.name, methodName);
+ expect(method.functions, hasLength(0));
+ expect(method.labels, hasLength(0));
+ expect(method.localVariables, hasLength(0));
+ expect(method.parameters, hasLength(0));
+ expect(method.typeParameters, hasLength(1));
+ expect(method.isAbstract, isFalse);
+ expect(method.isExternal, isFalse);
+ expect(method.isStatic, isFalse);
+ expect(method.isSynthetic, isFalse);
+ }
+
+ void test_visitMethodDeclaration_withMembers() {
+ // m(p) { var v; try { l: return; } catch (e) {} }
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String methodName = "m";
+ String parameterName = "p";
+ String localVariableName = "v";
+ String labelName = "l";
+ String exceptionParameterName = "e";
+ MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3(methodName),
+ AstFactory.formalParameterList(
+ [AstFactory.simpleFormalParameter3(parameterName)]),
+ AstFactory.blockFunctionBody2([
+ AstFactory.variableDeclarationStatement2(
+ Keyword.VAR, [AstFactory.variableDeclaration(localVariableName)]),
+ AstFactory.tryStatement2(
+ AstFactory.block([
+ AstFactory.labeledStatement([AstFactory.label2(labelName)],
+ AstFactory.returnStatement())
+ ]),
+ [AstFactory.catchClause(exceptionParameterName)])
+ ]));
+ methodDeclaration.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ MethodElement method = methods[0];
+ expect(method, isNotNull);
+ expect(method.hasImplicitReturnType, isTrue);
+ expect(method.name, methodName);
+ expect(method.typeParameters, hasLength(0));
+ expect(method.isAbstract, isFalse);
+ expect(method.isExternal, isFalse);
+ expect(method.isStatic, isFalse);
+ expect(method.isSynthetic, isFalse);
+ List<VariableElement> parameters = method.parameters;
+ expect(parameters, hasLength(1));
+ VariableElement parameter = parameters[0];
+ expect(parameter, isNotNull);
+ expect(parameter.name, parameterName);
+ List<VariableElement> localVariables = method.localVariables;
+ expect(localVariables, hasLength(2));
+ VariableElement firstVariable = localVariables[0];
+ VariableElement secondVariable = localVariables[1];
+ expect(firstVariable, isNotNull);
+ expect(secondVariable, isNotNull);
+ expect(
+ (firstVariable.name == localVariableName &&
+ secondVariable.name == exceptionParameterName) ||
+ (firstVariable.name == exceptionParameterName &&
+ secondVariable.name == localVariableName),
+ isTrue);
+ List<LabelElement> labels = method.labels;
+ expect(labels, hasLength(1));
+ LabelElement label = labels[0];
+ expect(label, isNotNull);
+ expect(label.name, labelName);
+ }
+
+ void test_visitNamedFormalParameter() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = "p";
+ DefaultFormalParameter formalParameter = AstFactory.namedFormalParameter(
+ AstFactory.simpleFormalParameter3(parameterName),
+ AstFactory.identifier3("42"));
+ _useParameterInMethod(formalParameter, 100, 110);
+ formalParameter.accept(builder);
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter, isNotNull);
+ expect(parameter.name, parameterName);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.parameterKind, ParameterKind.NAMED);
+ {
+ SourceRange visibleRange = parameter.visibleRange;
+ expect(100, visibleRange.offset);
+ expect(110, visibleRange.end);
+ }
+ expect(parameter.defaultValueCode, "42");
+ FunctionElement initializer = parameter.initializer;
+ expect(initializer, isNotNull);
+ expect(initializer.isSynthetic, isTrue);
+ }
+
+ void test_visitSimpleFormalParameter_noType() {
+ // p
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = "p";
+ SimpleFormalParameter formalParameter =
+ AstFactory.simpleFormalParameter3(parameterName);
+ _useParameterInMethod(formalParameter, 100, 110);
+ formalParameter.accept(builder);
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter, isNotNull);
+ expect(parameter.hasImplicitType, isTrue);
+ expect(parameter.initializer, isNull);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.name, parameterName);
+ expect(parameter.parameterKind, ParameterKind.REQUIRED);
+ {
+ SourceRange visibleRange = parameter.visibleRange;
+ expect(100, visibleRange.offset);
+ expect(110, visibleRange.end);
+ }
+ }
+
+ void test_visitSimpleFormalParameter_type() {
+ // T p
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = "p";
+ SimpleFormalParameter formalParameter = AstFactory.simpleFormalParameter4(
+ AstFactory.typeName4('T'), parameterName);
+ _useParameterInMethod(formalParameter, 100, 110);
+ formalParameter.accept(builder);
+ List<ParameterElement> parameters = holder.parameters;
+ expect(parameters, hasLength(1));
+ ParameterElement parameter = parameters[0];
+ expect(parameter, isNotNull);
+ expect(parameter.hasImplicitType, isFalse);
+ expect(parameter.initializer, isNull);
+ expect(parameter.isConst, isFalse);
+ expect(parameter.isFinal, isFalse);
+ expect(parameter.isSynthetic, isFalse);
+ expect(parameter.name, parameterName);
+ expect(parameter.parameterKind, ParameterKind.REQUIRED);
+ {
+ SourceRange visibleRange = parameter.visibleRange;
+ expect(100, visibleRange.offset);
+ expect(110, visibleRange.end);
+ }
+ }
+
+ void test_visitTypeAlias_minimal() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String aliasName = "F";
+ TypeAlias typeAlias = AstFactory.typeAlias(null, aliasName, null, null);
+ typeAlias.accept(builder);
+ List<FunctionTypeAliasElement> aliases = holder.typeAliases;
+ expect(aliases, hasLength(1));
+ FunctionTypeAliasElement alias = aliases[0];
+ expect(alias, isNotNull);
+ expect(alias.name, aliasName);
+ expect(alias.type, isNotNull);
+ expect(alias.isSynthetic, isFalse);
+ }
+
+ void test_visitTypeAlias_withFormalParameters() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String aliasName = "F";
+ String firstParameterName = "x";
+ String secondParameterName = "y";
+ TypeAlias typeAlias = AstFactory.typeAlias(
+ null,
+ aliasName,
+ AstFactory.typeParameterList(),
+ AstFactory.formalParameterList([
+ AstFactory.simpleFormalParameter3(firstParameterName),
+ AstFactory.simpleFormalParameter3(secondParameterName)
+ ]));
+ typeAlias.accept(builder);
+ List<FunctionTypeAliasElement> aliases = holder.typeAliases;
+ expect(aliases, hasLength(1));
+ FunctionTypeAliasElement alias = aliases[0];
+ expect(alias, isNotNull);
+ expect(alias.name, aliasName);
+ expect(alias.type, isNotNull);
+ expect(alias.isSynthetic, isFalse);
+ List<VariableElement> parameters = alias.parameters;
+ expect(parameters, hasLength(2));
+ expect(parameters[0].name, firstParameterName);
+ expect(parameters[1].name, secondParameterName);
+ List<TypeParameterElement> typeParameters = alias.typeParameters;
+ expect(typeParameters, isNotNull);
+ expect(typeParameters, hasLength(0));
+ }
+
+ void test_visitTypeAlias_withTypeParameters() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String aliasName = "F";
+ String firstTypeParameterName = "A";
+ String secondTypeParameterName = "B";
+ TypeAlias typeAlias = AstFactory.typeAlias(
+ null,
+ aliasName,
+ AstFactory.typeParameterList(
+ [firstTypeParameterName, secondTypeParameterName]),
+ AstFactory.formalParameterList());
+ typeAlias.accept(builder);
+ List<FunctionTypeAliasElement> aliases = holder.typeAliases;
+ expect(aliases, hasLength(1));
+ FunctionTypeAliasElement alias = aliases[0];
+ expect(alias, isNotNull);
+ expect(alias.name, aliasName);
+ expect(alias.type, isNotNull);
+ expect(alias.isSynthetic, isFalse);
+ List<VariableElement> parameters = alias.parameters;
+ expect(parameters, isNotNull);
+ expect(parameters, hasLength(0));
+ List<TypeParameterElement> typeParameters = alias.typeParameters;
+ expect(typeParameters, hasLength(2));
+ expect(typeParameters[0].name, firstTypeParameterName);
+ expect(typeParameters[1].name, secondTypeParameterName);
+ }
+
+ void test_visitTypeParameter() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String parameterName = "E";
+ TypeParameter typeParameter = AstFactory.typeParameter(parameterName);
+ typeParameter.accept(builder);
+ List<TypeParameterElement> typeParameters = holder.typeParameters;
+ expect(typeParameters, hasLength(1));
+ TypeParameterElement typeParameterElement = typeParameters[0];
+ expect(typeParameterElement, isNotNull);
+ expect(typeParameterElement.name, parameterName);
+ expect(typeParameterElement.bound, isNull);
+ expect(typeParameterElement.isSynthetic, isFalse);
+ }
+
+ void test_visitVariableDeclaration_inConstructor() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ //
+ // C() {var v;}
+ //
+ String variableName = "v";
+ VariableDeclaration variable =
+ AstFactory.variableDeclaration2(variableName, null);
+ Statement statement =
+ AstFactory.variableDeclarationStatement2(null, [variable]);
+ ConstructorDeclaration constructor = AstFactory.constructorDeclaration2(
+ null,
+ null,
+ AstFactory.identifier3("C"),
+ "C",
+ AstFactory.formalParameterList(),
+ null,
+ AstFactory.blockFunctionBody2([statement]));
+ constructor.accept(builder);
+
+ List<ConstructorElement> constructors = holder.constructors;
+ expect(constructors, hasLength(1));
+ List<LocalVariableElement> variableElements =
+ constructors[0].localVariables;
+ expect(variableElements, hasLength(1));
+ LocalVariableElement variableElement = variableElements[0];
+ expect(variableElement.hasImplicitType, isTrue);
+ expect(variableElement.name, variableName);
+ }
+
+ void test_visitVariableDeclaration_inMethod() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ //
+ // m() {T v;}
+ //
+ String variableName = "v";
+ VariableDeclaration variable =
+ AstFactory.variableDeclaration2(variableName, null);
+ Statement statement = AstFactory.variableDeclarationStatement(
+ null, AstFactory.typeName4('T'), [variable]);
+ MethodDeclaration method = AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3("m"),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2([statement]));
+ method.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ List<LocalVariableElement> variableElements = methods[0].localVariables;
+ expect(variableElements, hasLength(1));
+ LocalVariableElement variableElement = variableElements[0];
+ expect(variableElement.hasImplicitType, isFalse);
+ expect(variableElement.name, variableName);
+ }
+
+ void test_visitVariableDeclaration_localNestedInFunction() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ //
+ // var f = () {var v;};
+ //
+ String variableName = "v";
+ VariableDeclaration variable =
+ AstFactory.variableDeclaration2(variableName, null);
+ Statement statement =
+ AstFactory.variableDeclarationStatement2(null, [variable]);
+ Expression initializer = AstFactory.functionExpression2(
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2([statement]));
+ String fieldName = "f";
+ VariableDeclaration field =
+ AstFactory.variableDeclaration2(fieldName, initializer);
+ FieldDeclaration fieldDeclaration =
+ AstFactory.fieldDeclaration2(false, null, [field]);
+ fieldDeclaration.accept(builder);
+
+ List<FieldElement> variables = holder.fields;
+ expect(variables, hasLength(1));
+ FieldElement fieldElement = variables[0];
+ expect(fieldElement, isNotNull);
+ FunctionElement initializerElement = fieldElement.initializer;
+ expect(initializerElement, isNotNull);
+ List<FunctionElement> functionElements = initializerElement.functions;
+ expect(functionElements, hasLength(1));
+ List<LocalVariableElement> variableElements =
+ functionElements[0].localVariables;
+ expect(variableElements, hasLength(1));
+ LocalVariableElement variableElement = variableElements[0];
+ expect(variableElement.hasImplicitType, isTrue);
+ expect(variableElement.isConst, isFalse);
+ expect(variableElement.isFinal, isFalse);
+ expect(variableElement.isSynthetic, isFalse);
+ expect(variableElement.name, variableName);
+ }
+
+ void test_visitVariableDeclaration_noInitializer() {
+ // var v;
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String variableName = "v";
+ VariableDeclaration variableDeclaration =
+ AstFactory.variableDeclaration2(variableName, null);
+ AstFactory.variableDeclarationList2(null, [variableDeclaration]);
+ variableDeclaration.accept(builder);
+
+ List<TopLevelVariableElement> variables = holder.topLevelVariables;
+ expect(variables, hasLength(1));
+ TopLevelVariableElement variable = variables[0];
+ expect(variable, isNotNull);
+ expect(variable.hasImplicitType, isTrue);
+ expect(variable.initializer, isNull);
+ expect(variable.name, variableName);
+ expect(variable.isConst, isFalse);
+ expect(variable.isFinal, isFalse);
+ expect(variable.isSynthetic, isFalse);
+ expect(variable.getter, isNotNull);
+ expect(variable.setter, isNotNull);
+ }
+
+ void test_visitVariableDeclaration_top_const_hasInitializer() {
+ // const v = 42;
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String variableName = "v";
+ VariableDeclaration variableDeclaration =
+ AstFactory.variableDeclaration2(variableName, AstFactory.integer(42));
+ AstFactory.variableDeclarationList2(Keyword.CONST, [variableDeclaration]);
+ variableDeclaration.accept(builder);
+
+ List<TopLevelVariableElement> variables = holder.topLevelVariables;
+ expect(variables, hasLength(1));
+ TopLevelVariableElement variable = variables[0];
+ expect(variable, new isInstanceOf<ConstTopLevelVariableElementImpl>());
+ expect(variable.initializer, isNotNull);
+ expect(variable.name, variableName);
+ expect(variable.hasImplicitType, isTrue);
+ expect(variable.isConst, isTrue);
+ expect(variable.isFinal, isFalse);
+ expect(variable.isSynthetic, isFalse);
+ expect(variable.getter, isNotNull);
+ expect(variable.setter, isNull);
+ }
+
+ void test_visitVariableDeclaration_top_final() {
+ // final v;
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = new ElementBuilder(holder);
+ String variableName = "v";
+ VariableDeclaration variableDeclaration =
+ AstFactory.variableDeclaration2(variableName, null);
+ AstFactory.variableDeclarationList2(Keyword.FINAL, [variableDeclaration]);
+ variableDeclaration.accept(builder);
+ List<TopLevelVariableElement> variables = holder.topLevelVariables;
+ expect(variables, hasLength(1));
+ TopLevelVariableElement variable = variables[0];
+ expect(variable, isNotNull);
+ expect(variable.hasImplicitType, isTrue);
+ expect(variable.initializer, isNull);
+ expect(variable.name, variableName);
+ expect(variable.isConst, isFalse);
+ expect(variable.isFinal, isTrue);
+ expect(variable.isSynthetic, isFalse);
+ expect(variable.getter, isNotNull);
+ expect(variable.setter, isNull);
+ }
+
+ void _assertHasDocRange(
+ Element element, int expectedOffset, int expectedLength) {
+ SourceRange docRange = element.docRange;
+ expect(docRange, isNotNull);
+ expect(docRange.offset, expectedOffset);
+ expect(docRange.length, expectedLength);
+ }
+
+ void _useParameterInMethod(
+ FormalParameter formalParameter, int blockOffset, int blockEnd) {
+ Block block = AstFactory.block();
+ block.leftBracket.offset = blockOffset;
+ block.rightBracket.offset = blockEnd - 1;
+ BlockFunctionBody body = AstFactory.blockFunctionBody(block);
+ AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3("main"),
+ AstFactory.formalParameterList([formalParameter]),
+ body);
+ }
+}
+
+@reflectiveTest
+class ElementLocatorTest extends ResolverTestCase {
+ void fail_locate_ExportDirective() {
+ AstNode id = _findNodeIn("export", "export 'dart:core';");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ImportElement, ImportElement, element);
+ }
+
+ void fail_locate_Identifier_libraryDirective() {
+ AstNode id = _findNodeIn("foo", "library foo.bar;");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is LibraryElement, LibraryElement, element);
+ }
+
+ void fail_locate_Identifier_partOfDirective() {
+ // Can't resolve the library element without the library declaration.
+ // AstNode id = findNodeIn("foo", "part of foo.bar;");
+ // Element element = ElementLocator.locate(id);
+ // assertInstanceOf(LibraryElement.class, element);
+ fail("Test this case");
+ }
+
+ @override
+ void reset() {
+ AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
+ analysisOptions.hint = false;
+ resetWithOptions(analysisOptions);
+ }
+
+ void test_locate_AssignmentExpression() {
+ AstNode id = _findNodeIn(
+ "+=",
+ r'''
+int x = 0;
+void main() {
+ x += 1;
+}''');
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodElement, MethodElement, element);
+ }
+
+ void test_locate_BinaryExpression() {
+ AstNode id = _findNodeIn("+", "var x = 3 + 4;");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodElement, MethodElement, element);
+ }
+
+ void test_locate_ClassDeclaration() {
+ AstNode id = _findNodeIn("class", "class A { }");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ClassElement, ClassElement, element);
+ }
+
+ void test_locate_CompilationUnit() {
+ CompilationUnit cu = _resolveContents("// only comment");
+ expect(cu.element, isNotNull);
+ Element element = ElementLocator.locate(cu);
+ expect(element, same(cu.element));
+ }
+
+ void test_locate_ConstructorDeclaration() {
+ AstNode id = _findNodeIndexedIn(
+ "bar",
+ 0,
+ r'''
+class A {
+ A.bar() {}
+}''');
+ ConstructorDeclaration declaration =
+ id.getAncestor((node) => node is ConstructorDeclaration);
+ Element element = ElementLocator.locate(declaration);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ConstructorElement, ConstructorElement, element);
+ }
+
+ void test_locate_FunctionDeclaration() {
+ AstNode id = _findNodeIn("f", "int f() => 3;");
+ FunctionDeclaration declaration =
+ id.getAncestor((node) => node is FunctionDeclaration);
+ Element element = ElementLocator.locate(declaration);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is FunctionElement, FunctionElement, element);
+ }
+
+ void test_locate_Identifier_annotationClass_namedConstructor_forSimpleFormalParameter() {
+ AstNode id = _findNodeIndexedIn(
+ "Class",
+ 2,
+ r'''
+class Class {
+ const Class.name();
+}
+void main(@Class.name() parameter) {
+}''');
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ClassElement, ClassElement, element);
+ }
+
+ void test_locate_Identifier_annotationClass_unnamedConstructor_forSimpleFormalParameter() {
+ AstNode id = _findNodeIndexedIn(
+ "Class",
+ 2,
+ r'''
+class Class {
+ const Class();
+}
+void main(@Class() parameter) {
+}''');
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ConstructorElement, ConstructorElement, element);
+ }
+
+ void test_locate_Identifier_className() {
+ AstNode id = _findNodeIn("A", "class A { }");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ClassElement, ClassElement, element);
+ }
+
+ void test_locate_Identifier_constructor_named() {
+ AstNode id = _findNodeIndexedIn(
+ "bar",
+ 0,
+ r'''
+class A {
+ A.bar() {}
+}''');
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ConstructorElement, ConstructorElement, element);
+ }
+
+ void test_locate_Identifier_constructor_unnamed() {
+ AstNode id = _findNodeIndexedIn(
+ "A",
+ 1,
+ r'''
+class A {
+ A() {}
+}''');
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ConstructorElement, ConstructorElement, element);
+ }
+
+ void test_locate_Identifier_fieldName() {
+ AstNode id = _findNodeIn("x", "class A { var x; }");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is FieldElement, FieldElement, element);
+ }
+
+ void test_locate_Identifier_propertAccess() {
+ AstNode id = _findNodeIn(
+ "length",
+ r'''
+void main() {
+ int x = 'foo'.length;
+}''');
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
+ PropertyAccessorElement, element);
+ }
+
+ void test_locate_ImportDirective() {
+ AstNode id = _findNodeIn("import", "import 'dart:core';");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ImportElement, ImportElement, element);
+ }
+
+ void test_locate_IndexExpression() {
+ AstNode id = _findNodeIndexedIn(
+ "\\[",
+ 1,
+ r'''
+void main() {
+ List x = [1, 2];
+ var y = x[0];
+}''');
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodElement, MethodElement, element);
+ }
+
+ void test_locate_InstanceCreationExpression() {
+ AstNode node = _findNodeIndexedIn(
+ "A(",
+ 0,
+ r'''
+class A {}
+void main() {
+ new A();
+}''');
+ Element element = ElementLocator.locate(node);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ConstructorElement, ConstructorElement, element);
+ }
+
+ void test_locate_InstanceCreationExpression_type_prefixedIdentifier() {
+ // prepare: new pref.A()
+ SimpleIdentifier identifier = AstFactory.identifier3("A");
+ PrefixedIdentifier prefixedIdentifier =
+ AstFactory.identifier4("pref", identifier);
+ InstanceCreationExpression creation = AstFactory
+ .instanceCreationExpression2(
+ Keyword.NEW, AstFactory.typeName3(prefixedIdentifier));
+ // set ClassElement
+ ClassElement classElement = ElementFactory.classElement2("A");
+ identifier.staticElement = classElement;
+ // set ConstructorElement
+ ConstructorElement constructorElement =
+ ElementFactory.constructorElement2(classElement, null);
+ creation.constructorName.staticElement = constructorElement;
+ // verify that "A" is resolved to ConstructorElement
+ Element element = ElementLocator.locate(identifier);
+ expect(element, same(classElement));
+ }
+
+ void test_locate_InstanceCreationExpression_type_simpleIdentifier() {
+ // prepare: new A()
+ SimpleIdentifier identifier = AstFactory.identifier3("A");
+ InstanceCreationExpression creation = AstFactory
+ .instanceCreationExpression2(
+ Keyword.NEW, AstFactory.typeName3(identifier));
+ // set ClassElement
+ ClassElement classElement = ElementFactory.classElement2("A");
+ identifier.staticElement = classElement;
+ // set ConstructorElement
+ ConstructorElement constructorElement =
+ ElementFactory.constructorElement2(classElement, null);
+ creation.constructorName.staticElement = constructorElement;
+ // verify that "A" is resolved to ConstructorElement
+ Element element = ElementLocator.locate(identifier);
+ expect(element, same(classElement));
+ }
+
+ void test_locate_LibraryDirective() {
+ AstNode id = _findNodeIn("library", "library foo;");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is LibraryElement, LibraryElement, element);
+ }
+
+ void test_locate_MethodDeclaration() {
+ AstNode id = _findNodeIn(
+ "m",
+ r'''
+class A {
+ void m() {}
+}''');
+ MethodDeclaration declaration =
+ id.getAncestor((node) => node is MethodDeclaration);
+ Element element = ElementLocator.locate(declaration);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodElement, MethodElement, element);
+ }
+
+ void test_locate_MethodInvocation_method() {
+ AstNode id = _findNodeIndexedIn(
+ "bar",
+ 1,
+ r'''
+class A {
+ int bar() => 42;
+}
+void main() {
+ var f = new A().bar();
+}''');
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodElement, MethodElement, element);
+ }
+
+ void test_locate_MethodInvocation_topLevel() {
+ String code = r'''
+foo(x) {}
+void main() {
+ foo(0);
+}''';
+ CompilationUnit cu = _resolveContents(code);
+ int offset = code.indexOf('foo(0)');
+ AstNode node = new NodeLocator(offset).searchWithin(cu);
+ MethodInvocation invocation =
+ node.getAncestor((n) => n is MethodInvocation);
+ Element element = ElementLocator.locate(invocation);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is FunctionElement, FunctionElement, element);
+ }
+
+ void test_locate_PartOfDirective() {
+ Source librarySource = addNamedSource(
+ '/lib.dart',
+ '''
+library my.lib;
+part 'part.dart';
+''');
+ Source unitSource = addNamedSource(
+ '/part.dart',
+ '''
+part of my.lib;
+''');
+ CompilationUnit unit =
+ analysisContext.resolveCompilationUnit2(unitSource, librarySource);
+ PartOfDirective partOf = unit.directives.first;
+ Element element = ElementLocator.locate(partOf);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is LibraryElement, LibraryElement, element);
+ }
+
+ void test_locate_PostfixExpression() {
+ AstNode id = _findNodeIn("++", "int addOne(int x) => x++;");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodElement, MethodElement, element);
+ }
+
+ void test_locate_PrefixedIdentifier() {
+ AstNode id = _findNodeIn(
+ "int",
+ r'''
+import 'dart:core' as core;
+core.int value;''');
+ PrefixedIdentifier identifier =
+ id.getAncestor((node) => node is PrefixedIdentifier);
+ Element element = ElementLocator.locate(identifier);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ClassElement, ClassElement, element);
+ }
+
+ void test_locate_PrefixExpression() {
+ AstNode id = _findNodeIn("++", "int addOne(int x) => ++x;");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodElement, MethodElement, element);
+ }
+
+ void test_locate_StringLiteral_exportUri() {
+ addNamedSource("/foo.dart", "library foo;");
+ AstNode id = _findNodeIn("'foo.dart'", "export 'foo.dart';");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is LibraryElement, LibraryElement, element);
+ }
+
+ void test_locate_StringLiteral_expression() {
+ AstNode id = _findNodeIn("abc", "var x = 'abc';");
+ Element element = ElementLocator.locate(id);
+ expect(element, isNull);
+ }
+
+ void test_locate_StringLiteral_importUri() {
+ addNamedSource("/foo.dart", "library foo; class A {}");
+ AstNode id =
+ _findNodeIn("'foo.dart'", "import 'foo.dart'; class B extends A {}");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is LibraryElement, LibraryElement, element);
+ }
+
+ void test_locate_StringLiteral_partUri() {
+ addNamedSource("/foo.dart", "part of app;");
+ AstNode id = _findNodeIn("'foo.dart'", "library app; part 'foo.dart';");
+ Element element = ElementLocator.locate(id);
+ EngineTestCase.assertInstanceOf((obj) => obj is CompilationUnitElement,
+ CompilationUnitElement, element);
+ }
+
+ void test_locate_VariableDeclaration() {
+ AstNode id = _findNodeIn("x", "var x = 'abc';");
+ VariableDeclaration declaration =
+ id.getAncestor((node) => node is VariableDeclaration);
+ Element element = ElementLocator.locate(declaration);
+ EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableElement,
+ TopLevelVariableElement, element);
+ }
+
+ /**
+ * Find the first AST node matching a pattern in the resolved AST for the given source.
+ *
+ * [nodePattern] the (unique) pattern used to identify the node of interest.
+ * [code] the code to resolve.
+ * Returns the matched node in the resolved AST for the given source lines.
+ */
+ AstNode _findNodeIn(String nodePattern, String code) {
+ return _findNodeIndexedIn(nodePattern, 0, code);
+ }
+
+ /**
+ * Find the AST node matching the given indexed occurrence of a pattern in the resolved AST for
+ * the given source.
+ *
+ * [nodePattern] the pattern used to identify the node of interest.
+ * [index] the index of the pattern match of interest.
+ * [code] the code to resolve.
+ * Returns the matched node in the resolved AST for the given source lines
+ */
+ AstNode _findNodeIndexedIn(String nodePattern, int index, String code) {
+ CompilationUnit cu = _resolveContents(code);
+ int start = _getOffsetOfMatch(code, nodePattern, index);
+ int end = start + nodePattern.length;
+ return new NodeLocator(start, end).searchWithin(cu);
+ }
+
+ int _getOffsetOfMatch(String contents, String pattern, int matchIndex) {
+ if (matchIndex == 0) {
+ return contents.indexOf(pattern);
+ }
+ JavaPatternMatcher matcher =
+ new JavaPatternMatcher(new RegExp(pattern), contents);
+ int count = 0;
+ while (matcher.find()) {
+ if (count == matchIndex) {
+ return matcher.start();
+ }
+ ++count;
+ }
+ return -1;
+ }
+
+ /**
+ * Parse, resolve and verify the given source lines to produce a fully
+ * resolved AST.
+ *
+ * [code] the code to resolve.
+ *
+ * Returns the result of resolving the AST structure representing the content
+ * of the source.
+ *
+ * Throws if source cannot be verified.
+ */
+ CompilationUnit _resolveContents(String code) {
+ Source source = addSource(code);
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ return analysisContext.resolveCompilationUnit(source, library);
+ }
+}
+
+@reflectiveTest
+class EnumMemberBuilderTest extends EngineTestCase {
+ void test_visitEnumDeclaration_multiple() {
+ String firstName = "ONE";
+ String secondName = "TWO";
+ String thirdName = "THREE";
+ EnumDeclaration enumDeclaration =
+ AstFactory.enumDeclaration2("E", [firstName, secondName, thirdName]);
+
+ ClassElement enumElement = _buildElement(enumDeclaration);
+ List<FieldElement> fields = enumElement.fields;
+ expect(fields, hasLength(5));
+
+ FieldElement constant = fields[2];
+ expect(constant, isNotNull);
+ expect(constant.name, firstName);
+ expect(constant.isStatic, isTrue);
+ expect((constant as FieldElementImpl).evaluationResult, isNotNull);
+ _assertGetter(constant);
+
+ constant = fields[3];
+ expect(constant, isNotNull);
+ expect(constant.name, secondName);
+ expect(constant.isStatic, isTrue);
+ expect((constant as FieldElementImpl).evaluationResult, isNotNull);
+ _assertGetter(constant);
+
+ constant = fields[4];
+ expect(constant, isNotNull);
+ expect(constant.name, thirdName);
+ expect(constant.isStatic, isTrue);
+ expect((constant as FieldElementImpl).evaluationResult, isNotNull);
+ _assertGetter(constant);
+ }
+
+ void test_visitEnumDeclaration_single() {
+ String firstName = "ONE";
+ EnumDeclaration enumDeclaration =
+ AstFactory.enumDeclaration2("E", [firstName]);
+
+ ClassElement enumElement = _buildElement(enumDeclaration);
+ List<FieldElement> fields = enumElement.fields;
+ expect(fields, hasLength(3));
+
+ FieldElement field = fields[0];
+ expect(field, isNotNull);
+ expect(field.name, "index");
+ expect(field.isStatic, isFalse);
+ expect(field.isSynthetic, isTrue);
+ _assertGetter(field);
+
+ field = fields[1];
+ expect(field, isNotNull);
+ expect(field.name, "values");
+ expect(field.isStatic, isTrue);
+ expect(field.isSynthetic, isTrue);
+ expect((field as FieldElementImpl).evaluationResult, isNotNull);
+ _assertGetter(field);
+
+ FieldElement constant = fields[2];
+ expect(constant, isNotNull);
+ expect(constant.name, firstName);
+ expect(constant.isStatic, isTrue);
+ expect((constant as FieldElementImpl).evaluationResult, isNotNull);
+ _assertGetter(constant);
+ }
+
+ void _assertGetter(FieldElement field) {
+ PropertyAccessorElement getter = field.getter;
+ expect(getter, isNotNull);
+ expect(getter.variable, same(field));
+ expect(getter.type, isNotNull);
+ }
+
+ ClassElement _buildElement(EnumDeclaration enumDeclaration) {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder elementBuilder = new ElementBuilder(holder);
+ enumDeclaration.accept(elementBuilder);
+ EnumMemberBuilder memberBuilder =
+ new EnumMemberBuilder(new TestTypeProvider());
+ enumDeclaration.accept(memberBuilder);
+ List<ClassElement> enums = holder.enums;
+ expect(enums, hasLength(1));
+ return enums[0];
+ }
+}
+
+@reflectiveTest
+class ErrorReporterTest extends EngineTestCase {
+ /**
+ * Create a type with the given name in a compilation unit with the given name.
+ *
+ * @param fileName the name of the compilation unit containing the class
+ * @param typeName the name of the type to be created
+ * @return the type that was created
+ */
+ InterfaceType createType(String fileName, String typeName) {
+ CompilationUnitElementImpl unit = ElementFactory.compilationUnit(fileName);
+ ClassElementImpl element = ElementFactory.classElement2(typeName);
+ unit.types = <ClassElement>[element];
+ return element.type;
+ }
+
+ void test_creation() {
+ GatheringErrorListener listener = new GatheringErrorListener();
+ TestSource source = new TestSource();
+ expect(new ErrorReporter(listener, source), isNotNull);
+ }
+
+ void test_reportErrorForElement_named() {
+ DartType type = createType("/test1.dart", "A");
+ ClassElement element = type.element;
+ GatheringErrorListener listener = new GatheringErrorListener();
+ ErrorReporter reporter = new ErrorReporter(listener, element.source);
+ reporter.reportErrorForElement(
+ StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER,
+ element,
+ ['A']);
+ AnalysisError error = listener.errors[0];
+ expect(error.offset, element.nameOffset);
+ }
+
+ void test_reportErrorForElement_unnamed() {
+ ImportElementImpl element =
+ ElementFactory.importFor(ElementFactory.library(null, ''), null);
+ GatheringErrorListener listener = new GatheringErrorListener();
+ ErrorReporter reporter = new ErrorReporter(
+ listener,
+ new NonExistingSource(
+ '/test.dart', toUri('/test.dart'), UriKind.FILE_URI));
+ reporter.reportErrorForElement(
+ StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER,
+ element,
+ ['A']);
+ AnalysisError error = listener.errors[0];
+ expect(error.offset, element.nameOffset);
+ }
+
+ void test_reportTypeErrorForNode_differentNames() {
+ DartType firstType = createType("/test1.dart", "A");
+ DartType secondType = createType("/test2.dart", "B");
+ GatheringErrorListener listener = new GatheringErrorListener();
+ ErrorReporter reporter =
+ new ErrorReporter(listener, firstType.element.source);
+ reporter.reportTypeErrorForNode(
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+ AstFactory.identifier3("x"),
+ [firstType, secondType]);
+ AnalysisError error = listener.errors[0];
+ expect(error.message.indexOf("(") < 0, isTrue);
+ }
+
+ void test_reportTypeErrorForNode_sameName() {
+ String typeName = "A";
+ DartType firstType = createType("/test1.dart", typeName);
+ DartType secondType = createType("/test2.dart", typeName);
+ GatheringErrorListener listener = new GatheringErrorListener();
+ ErrorReporter reporter =
+ new ErrorReporter(listener, firstType.element.source);
+ reporter.reportTypeErrorForNode(
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+ AstFactory.identifier3("x"),
+ [firstType, secondType]);
+ AnalysisError error = listener.errors[0];
+ expect(error.message.indexOf("(") >= 0, isTrue);
+ }
+}
+
+@reflectiveTest
+class ErrorSeverityTest extends EngineTestCase {
+ void test_max_error_error() {
+ expect(ErrorSeverity.ERROR.max(ErrorSeverity.ERROR),
+ same(ErrorSeverity.ERROR));
+ }
+
+ void test_max_error_none() {
+ expect(
+ ErrorSeverity.ERROR.max(ErrorSeverity.NONE), same(ErrorSeverity.ERROR));
+ }
+
+ void test_max_error_warning() {
+ expect(ErrorSeverity.ERROR.max(ErrorSeverity.WARNING),
+ same(ErrorSeverity.ERROR));
+ }
+
+ void test_max_none_error() {
+ expect(
+ ErrorSeverity.NONE.max(ErrorSeverity.ERROR), same(ErrorSeverity.ERROR));
+ }
+
+ void test_max_none_none() {
+ expect(
+ ErrorSeverity.NONE.max(ErrorSeverity.NONE), same(ErrorSeverity.NONE));
+ }
+
+ void test_max_none_warning() {
+ expect(ErrorSeverity.NONE.max(ErrorSeverity.WARNING),
+ same(ErrorSeverity.WARNING));
+ }
+
+ void test_max_warning_error() {
+ expect(ErrorSeverity.WARNING.max(ErrorSeverity.ERROR),
+ same(ErrorSeverity.ERROR));
+ }
+
+ void test_max_warning_none() {
+ expect(ErrorSeverity.WARNING.max(ErrorSeverity.NONE),
+ same(ErrorSeverity.WARNING));
+ }
+
+ void test_max_warning_warning() {
+ expect(ErrorSeverity.WARNING.max(ErrorSeverity.WARNING),
+ same(ErrorSeverity.WARNING));
+ }
+}
+
+/**
+ * Tests for the [ExitDetector] that do not require that the AST be resolved.
+ *
+ * See [ExitDetectorTest2] for tests that require the AST to be resolved.
+ */
+@reflectiveTest
+class ExitDetectorTest extends ParserTestCase {
+ void fail_doStatement_continue_with_label() {
+ _assertFalse("{ x: do { continue x; } while(true); }");
+ }
+
+ void fail_whileStatement_continue_with_label() {
+ _assertFalse("{ x: while (true) { continue x; } }");
+ }
+
+ void fail_whileStatement_doStatement_scopeRequired() {
+ _assertTrue("{ while (true) { x: do { continue x; } while(true); }");
+ }
+
+ void test_asExpression() {
+ _assertFalse("a as Object;");
+ }
+
+ void test_asExpression_throw() {
+ _assertTrue("throw '' as Object;");
+ }
+
+ void test_assertStatement() {
+ _assertFalse("assert(a);");
+ }
+
+ void test_assertStatement_throw() {
+ _assertFalse("assert((throw 0));");
+ }
+
+ void test_assignmentExpression() {
+ _assertFalse("v = 1;");
+ }
+
+ void test_assignmentExpression_lhs_throw() {
+ _assertTrue("a[throw ''] = 0;");
+ }
+
+ void test_assignmentExpression_rhs_throw() {
+ _assertTrue("v = throw '';");
+ }
+
+ void test_await_false() {
+ _assertFalse("await x;");
+ }
+
+ void test_await_throw_true() {
+ _assertTrue("bool b = await (throw '' || true);");
+ }
+
+ void test_binaryExpression_and() {
+ _assertFalse("a && b;");
+ }
+
+ void test_binaryExpression_and_lhs() {
+ _assertTrue("throw '' && b;");
+ }
+
+ void test_binaryExpression_and_rhs() {
+ _assertFalse("a && (throw '');");
+ }
+
+ void test_binaryExpression_and_rhs2() {
+ _assertFalse("false && (throw '');");
+ }
+
+ void test_binaryExpression_and_rhs3() {
+ _assertTrue("true && (throw '');");
+ }
+
+ void test_binaryExpression_ifNull() {
+ _assertFalse("a ?? b;");
+ }
+
+ void test_binaryExpression_ifNull_lhs() {
+ _assertTrue("throw '' ?? b;");
+ }
+
+ void test_binaryExpression_ifNull_rhs() {
+ _assertFalse("a ?? (throw '');");
+ }
+
+ void test_binaryExpression_ifNull_rhs2() {
+ _assertFalse("null ?? (throw '');");
+ }
+
+ void test_binaryExpression_or() {
+ _assertFalse("a || b;");
+ }
+
+ void test_binaryExpression_or_lhs() {
+ _assertTrue("throw '' || b;");
+ }
+
+ void test_binaryExpression_or_rhs() {
+ _assertFalse("a || (throw '');");
+ }
+
+ void test_binaryExpression_or_rhs2() {
+ _assertFalse("true || (throw '');");
+ }
+
+ void test_binaryExpression_or_rhs3() {
+ _assertTrue("false || (throw '');");
+ }
+
+ void test_block_empty() {
+ _assertFalse("{}");
+ }
+
+ void test_block_noReturn() {
+ _assertFalse("{ int i = 0; }");
+ }
+
+ void test_block_return() {
+ _assertTrue("{ return 0; }");
+ }
+
+ void test_block_returnNotLast() {
+ _assertTrue("{ return 0; throw 'a'; }");
+ }
+
+ void test_block_throwNotLast() {
+ _assertTrue("{ throw 0; x = null; }");
+ }
+
+ void test_cascadeExpression_argument() {
+ _assertTrue("a..b(throw '');");
+ }
+
+ void test_cascadeExpression_index() {
+ _assertTrue("a..[throw ''];");
+ }
+
+ void test_cascadeExpression_target() {
+ _assertTrue("throw ''..b();");
+ }
+
+ void test_conditional_ifElse_bothThrows() {
+ _assertTrue("c ? throw '' : throw '';");
+ }
+
+ void test_conditional_ifElse_elseThrows() {
+ _assertFalse("c ? i : throw '';");
+ }
+
+ void test_conditional_ifElse_noThrow() {
+ _assertFalse("c ? i : j;");
+ }
+
+ void test_conditional_ifElse_thenThrow() {
+ _assertFalse("c ? throw '' : j;");
+ }
+
+ void test_conditionalAccess() {
+ _assertFalse("a?.b;");
+ }
+
+ void test_conditionalAccess_lhs() {
+ _assertTrue("(throw '')?.b;");
+ }
+
+ void test_conditionalAccessAssign() {
+ _assertFalse("a?.b = c;");
+ }
+
+ void test_conditionalAccessAssign_lhs() {
+ _assertTrue("(throw '')?.b = c;");
+ }
+
+ void test_conditionalAccessAssign_rhs() {
+ _assertFalse("a?.b = throw '';");
+ }
+
+ void test_conditionalAccessAssign_rhs2() {
+ _assertFalse("null?.b = throw '';");
+ }
+
+ void test_conditionalAccessIfNullAssign() {
+ _assertFalse("a?.b ??= c;");
+ }
+
+ void test_conditionalAccessIfNullAssign_lhs() {
+ _assertTrue("(throw '')?.b ??= c;");
+ }
+
+ void test_conditionalAccessIfNullAssign_rhs() {
+ _assertFalse("a?.b ??= throw '';");
+ }
+
+ void test_conditionalAccessIfNullAssign_rhs2() {
+ _assertFalse("null?.b ??= throw '';");
+ }
+
+ void test_conditionalCall() {
+ _assertFalse("a?.b(c);");
+ }
+
+ void test_conditionalCall_lhs() {
+ _assertTrue("(throw '')?.b(c);");
+ }
+
+ void test_conditionalCall_rhs() {
+ _assertFalse("a?.b(throw '');");
+ }
+
+ void test_conditionalCall_rhs2() {
+ _assertFalse("null?.b(throw '');");
+ }
+
+ void test_creation() {
+ expect(new ExitDetector(), isNotNull);
+ }
+
+ void test_doStatement_throwCondition() {
+ _assertTrue("{ do {} while (throw ''); }");
+ }
+
+ void test_doStatement_true_break() {
+ _assertFalse("{ do { break; } while (true); }");
+ }
+
+ void test_doStatement_true_continue() {
+ _assertTrue("{ do { continue; } while (true); }");
+ }
+
+ void test_doStatement_true_if_return() {
+ _assertTrue("{ do { if (true) {return null;} } while (true); }");
+ }
+
+ void test_doStatement_true_noBreak() {
+ _assertTrue("{ do {} while (true); }");
+ }
+
+ void test_doStatement_true_return() {
+ _assertTrue("{ do { return null; } while (true); }");
+ }
+
+ void test_emptyStatement() {
+ _assertFalse(";");
+ }
+
+ void test_forEachStatement() {
+ _assertFalse("for (element in list) {}");
+ }
+
+ void test_forEachStatement_throw() {
+ _assertTrue("for (element in throw '') {}");
+ }
+
+ void test_forStatement_condition() {
+ _assertTrue("for (; throw 0;) {}");
+ }
+
+ void test_forStatement_implicitTrue() {
+ _assertTrue("for (;;) {}");
+ }
+
+ void test_forStatement_implicitTrue_break() {
+ _assertFalse("for (;;) { break; }");
+ }
+
+ void test_forStatement_initialization() {
+ _assertTrue("for (i = throw 0;;) {}");
+ }
+
+ void test_forStatement_true() {
+ _assertTrue("for (; true; ) {}");
+ }
+
+ void test_forStatement_true_break() {
+ _assertFalse("{ for (; true; ) { break; } }");
+ }
+
+ void test_forStatement_true_continue() {
+ _assertTrue("{ for (; true; ) { continue; } }");
+ }
+
+ void test_forStatement_true_if_return() {
+ _assertTrue("{ for (; true; ) { if (true) {return null;} } }");
+ }
+
+ void test_forStatement_true_noBreak() {
+ _assertTrue("{ for (; true; ) {} }");
+ }
+
+ void test_forStatement_updaters() {
+ _assertTrue("for (;; i++, throw 0) {}");
+ }
+
+ void test_forStatement_variableDeclaration() {
+ _assertTrue("for (int i = throw 0;;) {}");
+ }
+
+ void test_functionExpression() {
+ _assertFalse("(){};");
+ }
+
+ void test_functionExpression_bodyThrows() {
+ _assertFalse("(int i) => throw '';");
+ }
+
+ void test_functionExpressionInvocation() {
+ _assertFalse("f(g);");
+ }
+
+ void test_functionExpressionInvocation_argumentThrows() {
+ _assertTrue("f(throw '');");
+ }
+
+ void test_functionExpressionInvocation_targetThrows() {
+ _assertTrue("throw ''(g);");
+ }
+
+ void test_identifier_prefixedIdentifier() {
+ _assertFalse("a.b;");
+ }
+
+ void test_identifier_simpleIdentifier() {
+ _assertFalse("a;");
+ }
+
+ void test_if_false_else_return() {
+ _assertTrue("if (false) {} else { return 0; }");
+ }
+
+ void test_if_false_noReturn() {
+ _assertFalse("if (false) {}");
+ }
+
+ void test_if_false_return() {
+ _assertFalse("if (false) { return 0; }");
+ }
+
+ void test_if_noReturn() {
+ _assertFalse("if (c) i++;");
+ }
+
+ void test_if_return() {
+ _assertFalse("if (c) return 0;");
+ }
+
+ void test_if_true_noReturn() {
+ _assertFalse("if (true) {}");
+ }
+
+ void test_if_true_return() {
+ _assertTrue("if (true) { return 0; }");
+ }
+
+ void test_ifElse_bothReturn() {
+ _assertTrue("if (c) return 0; else return 1;");
+ }
+
+ void test_ifElse_elseReturn() {
+ _assertFalse("if (c) i++; else return 1;");
+ }
+
+ void test_ifElse_noReturn() {
+ _assertFalse("if (c) i++; else j++;");
+ }
+
+ void test_ifElse_thenReturn() {
+ _assertFalse("if (c) return 0; else j++;");
+ }
+
+ void test_ifNullAssign() {
+ _assertFalse("a ??= b;");
+ }
+
+ void test_ifNullAssign_rhs() {
+ _assertFalse("a ??= throw '';");
+ }
+
+ void test_indexExpression() {
+ _assertFalse("a[b];");
+ }
+
+ void test_indexExpression_index() {
+ _assertTrue("a[throw ''];");
+ }
+
+ void test_indexExpression_target() {
+ _assertTrue("throw ''[b];");
+ }
+
+ void test_instanceCreationExpression() {
+ _assertFalse("new A(b);");
+ }
+
+ void test_instanceCreationExpression_argumentThrows() {
+ _assertTrue("new A(throw '');");
+ }
+
+ void test_isExpression() {
+ _assertFalse("A is B;");
+ }
+
+ void test_isExpression_throws() {
+ _assertTrue("throw '' is B;");
+ }
+
+ void test_labeledStatement() {
+ _assertFalse("label: a;");
+ }
+
+ void test_labeledStatement_throws() {
+ _assertTrue("label: throw '';");
+ }
+
+ void test_literal_boolean() {
+ _assertFalse("true;");
+ }
+
+ void test_literal_double() {
+ _assertFalse("1.1;");
+ }
+
+ void test_literal_integer() {
+ _assertFalse("1;");
+ }
+
+ void test_literal_null() {
+ _assertFalse("null;");
+ }
+
+ void test_literal_String() {
+ _assertFalse("'str';");
+ }
+
+ void test_methodInvocation() {
+ _assertFalse("a.b(c);");
+ }
+
+ void test_methodInvocation_argument() {
+ _assertTrue("a.b(throw '');");
+ }
+
+ void test_methodInvocation_target() {
+ _assertTrue("throw ''.b(c);");
+ }
+
+ void test_parenthesizedExpression() {
+ _assertFalse("(a);");
+ }
+
+ void test_parenthesizedExpression_throw() {
+ _assertTrue("(throw '');");
+ }
+
+ void test_propertyAccess() {
+ _assertFalse("new Object().a;");
+ }
+
+ void test_propertyAccess_throws() {
+ _assertTrue("(throw '').a;");
+ }
+
+ void test_rethrow() {
+ _assertTrue("rethrow;");
+ }
+
+ void test_return() {
+ _assertTrue("return 0;");
+ }
+
+ void test_superExpression() {
+ _assertFalse("super.a;");
+ }
+
+ void test_switch_allReturn() {
+ _assertTrue("switch (i) { case 0: return 0; default: return 1; }");
+ }
+
+ void test_switch_defaultWithNoStatements() {
+ _assertFalse("switch (i) { case 0: return 0; default: }");
+ }
+
+ void test_switch_fallThroughToNotReturn() {
+ _assertFalse("switch (i) { case 0: case 1: break; default: return 1; }");
+ }
+
+ void test_switch_fallThroughToReturn() {
+ _assertTrue("switch (i) { case 0: case 1: return 0; default: return 1; }");
+ }
+
+ void test_switch_noDefault() {
+ _assertFalse("switch (i) { case 0: return 0; }");
+ }
+
+ void test_switch_nonReturn() {
+ _assertFalse("switch (i) { case 0: i++; default: return 1; }");
+ }
+
+ void test_thisExpression() {
+ _assertFalse("this.a;");
+ }
+
+ void test_throwExpression() {
+ _assertTrue("throw new Object();");
+ }
+
+ void test_tryStatement_noReturn() {
+ _assertFalse("try {} catch (e, s) {} finally {}");
+ }
+
+ void test_tryStatement_return_catch() {
+ _assertFalse("try {} catch (e, s) { return 1; } finally {}");
+ }
+
+ void test_tryStatement_return_finally() {
+ _assertTrue("try {} catch (e, s) {} finally { return 1; }");
+ }
+
+ void test_tryStatement_return_try() {
+ _assertTrue("try { return 1; } catch (e, s) {} finally {}");
+ }
+
+ void test_variableDeclarationStatement_noInitializer() {
+ _assertFalse("int i;");
+ }
+
+ void test_variableDeclarationStatement_noThrow() {
+ _assertFalse("int i = 0;");
+ }
+
+ void test_variableDeclarationStatement_throw() {
+ _assertTrue("int i = throw new Object();");
+ }
+
+ void test_whileStatement_false_nonReturn() {
+ _assertFalse("{ while (false) {} }");
+ }
+
+ void test_whileStatement_throwCondition() {
+ _assertTrue("{ while (throw '') {} }");
+ }
+
+ void test_whileStatement_true_break() {
+ _assertFalse("{ while (true) { break; } }");
+ }
+
+ void test_whileStatement_true_continue() {
+ _assertTrue("{ while (true) { continue; } }");
+ }
+
+ void test_whileStatement_true_if_return() {
+ _assertTrue("{ while (true) { if (true) {return null;} } }");
+ }
+
+ void test_whileStatement_true_noBreak() {
+ _assertTrue("{ while (true) {} }");
+ }
+
+ void test_whileStatement_true_return() {
+ _assertTrue("{ while (true) { return null; } }");
+ }
+
+ void test_whileStatement_true_throw() {
+ _assertTrue("{ while (true) { throw ''; } }");
+ }
+
+ void _assertFalse(String source) {
+ _assertHasReturn(false, source);
+ }
+
+ void _assertHasReturn(bool expectedResult, String source) {
+ Statement statement = ParserTestCase.parseStatement(source);
+ expect(ExitDetector.exits(statement), expectedResult);
+ }
+
+ void _assertTrue(String source) {
+ _assertHasReturn(true, source);
+ }
+}
+
+/**
+ * Tests for the [ExitDetector] that require that the AST be resolved.
+ *
+ * See [ExitDetectorTest] for tests that do not require the AST to be resolved.
+ */
+@reflectiveTest
+class ExitDetectorTest2 extends ResolverTestCase {
+ void test_switch_withEnum_false_noDefault() {
+ Source source = addSource(r'''
+enum E { A, B }
+String f(E e) {
+ var x;
+ switch (e) {
+ case A:
+ x = 'A';
+ case B:
+ x = 'B';
+ }
+ return x;
+}
+''');
+ LibraryElement element = resolve2(source);
+ CompilationUnit unit = resolveCompilationUnit(source, element);
+ FunctionDeclaration function = unit.declarations.last;
+ BlockFunctionBody body = function.functionExpression.body;
+ Statement statement = body.block.statements[1];
+ expect(ExitDetector.exits(statement), false);
+ }
+
+ void test_switch_withEnum_false_withDefault() {
+ Source source = addSource(r'''
+enum E { A, B }
+String f(E e) {
+ var x;
+ switch (e) {
+ case A:
+ x = 'A';
+ default:
+ x = '?';
+ }
+ return x;
+}
+''');
+ LibraryElement element = resolve2(source);
+ CompilationUnit unit = resolveCompilationUnit(source, element);
+ FunctionDeclaration function = unit.declarations.last;
+ BlockFunctionBody body = function.functionExpression.body;
+ Statement statement = body.block.statements[1];
+ expect(ExitDetector.exits(statement), false);
+ }
+
+ void test_switch_withEnum_true_noDefault() {
+ Source source = addSource(r'''
+enum E { A, B }
+String f(E e) {
+ switch (e) {
+ case A:
+ return 'A';
+ case B:
+ return 'B';
+ }
+}
+''');
+ LibraryElement element = resolve2(source);
+ CompilationUnit unit = resolveCompilationUnit(source, element);
+ FunctionDeclaration function = unit.declarations.last;
+ BlockFunctionBody body = function.functionExpression.body;
+ Statement statement = body.block.statements[0];
+ expect(ExitDetector.exits(statement), true);
+ }
+
+ void test_switch_withEnum_true_withDefault() {
+ Source source = addSource(r'''
+enum E { A, B }
+String f(E e) {
+ switch (e) {
+ case A:
+ return 'A';
+ default:
+ return '?';
+ }
+}
+''');
+ LibraryElement element = resolve2(source);
+ CompilationUnit unit = resolveCompilationUnit(source, element);
+ FunctionDeclaration function = unit.declarations.last;
+ BlockFunctionBody body = function.functionExpression.body;
+ Statement statement = body.block.statements[0];
+ expect(ExitDetector.exits(statement), true);
+ }
+}
+
+@reflectiveTest
+class FileBasedSourceTest {
+ void test_equals_false_differentFiles() {
+ JavaFile file1 = FileUtilities2.createFile("/does/not/exist1.dart");
+ JavaFile file2 = FileUtilities2.createFile("/does/not/exist2.dart");
+ FileBasedSource source1 = new FileBasedSource(file1);
+ FileBasedSource source2 = new FileBasedSource(file2);
+ expect(source1 == source2, isFalse);
+ }
+
+ void test_equals_false_null() {
+ JavaFile file = FileUtilities2.createFile("/does/not/exist1.dart");
+ FileBasedSource source1 = new FileBasedSource(file);
+ expect(source1 == null, isFalse);
+ }
+
+ void test_equals_true() {
+ JavaFile file1 = FileUtilities2.createFile("/does/not/exist.dart");
+ JavaFile file2 = FileUtilities2.createFile("/does/not/exist.dart");
+ FileBasedSource source1 = new FileBasedSource(file1);
+ FileBasedSource source2 = new FileBasedSource(file2);
+ expect(source1 == source2, isTrue);
+ }
+
+ void test_fileReadMode() {
+ expect(FileBasedSource.fileReadMode('a'), 'a');
+ expect(FileBasedSource.fileReadMode('a\n'), 'a\n');
+ expect(FileBasedSource.fileReadMode('ab'), 'ab');
+ expect(FileBasedSource.fileReadMode('abc'), 'abc');
+ expect(FileBasedSource.fileReadMode('a\nb'), 'a\nb');
+ expect(FileBasedSource.fileReadMode('a\rb'), 'a\rb');
+ expect(FileBasedSource.fileReadMode('a\r\nb'), 'a\r\nb');
+ }
+
+ void test_fileReadMode_changed() {
+ FileBasedSource.fileReadMode = (String s) => s + 'xyz';
+ expect(FileBasedSource.fileReadMode('a'), 'axyz');
+ expect(FileBasedSource.fileReadMode('a\n'), 'a\nxyz');
+ expect(FileBasedSource.fileReadMode('ab'), 'abxyz');
+ expect(FileBasedSource.fileReadMode('abc'), 'abcxyz');
+ FileBasedSource.fileReadMode = (String s) => s;
+ }
+
+ void test_fileReadMode_normalize_eol_always() {
+ FileBasedSource.fileReadMode =
+ PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS;
+ expect(FileBasedSource.fileReadMode('a'), 'a');
+
+ // '\n' -> '\n' as first, last and only character
+ expect(FileBasedSource.fileReadMode('\n'), '\n');
+ expect(FileBasedSource.fileReadMode('a\n'), 'a\n');
+ expect(FileBasedSource.fileReadMode('\na'), '\na');
+
+ // '\r\n' -> '\n' as first, last and only character
+ expect(FileBasedSource.fileReadMode('\r\n'), '\n');
+ expect(FileBasedSource.fileReadMode('a\r\n'), 'a\n');
+ expect(FileBasedSource.fileReadMode('\r\na'), '\na');
+
+ // '\r' -> '\n' as first, last and only character
+ expect(FileBasedSource.fileReadMode('\r'), '\n');
+ expect(FileBasedSource.fileReadMode('a\r'), 'a\n');
+ expect(FileBasedSource.fileReadMode('\ra'), '\na');
+
+ FileBasedSource.fileReadMode = (String s) => s;
+ }
+
+ void test_getEncoding() {
+ SourceFactory factory = new SourceFactory([new FileUriResolver()]);
+ String fullPath = "/does/not/exist.dart";
+ JavaFile file = FileUtilities2.createFile(fullPath);
+ FileBasedSource source = new FileBasedSource(file);
+ expect(factory.fromEncoding(source.encoding), source);
+ }
+
+ void test_getFullName() {
+ String fullPath = "/does/not/exist.dart";
+ JavaFile file = FileUtilities2.createFile(fullPath);
+ FileBasedSource source = new FileBasedSource(file);
+ expect(source.fullName, file.getAbsolutePath());
+ }
+
+ void test_getShortName() {
+ JavaFile file = FileUtilities2.createFile("/does/not/exist.dart");
+ FileBasedSource source = new FileBasedSource(file);
+ expect(source.shortName, "exist.dart");
+ }
+
+ void test_hashCode() {
+ JavaFile file1 = FileUtilities2.createFile("/does/not/exist.dart");
+ JavaFile file2 = FileUtilities2.createFile("/does/not/exist.dart");
+ FileBasedSource source1 = new FileBasedSource(file1);
+ FileBasedSource source2 = new FileBasedSource(file2);
+ expect(source2.hashCode, source1.hashCode);
+ }
+
+ void test_isInSystemLibrary_contagious() {
+ JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
+ expect(sdkDirectory, isNotNull);
+ DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+ UriResolver resolver = new DartUriResolver(sdk);
+ SourceFactory factory = new SourceFactory([resolver]);
+ // resolve dart:core
+ Source result =
+ resolver.resolveAbsolute(parseUriWithException("dart:core"));
+ expect(result, isNotNull);
+ expect(result.isInSystemLibrary, isTrue);
+ // system libraries reference only other system libraries
+ Source partSource = factory.resolveUri(result, "num.dart");
+ expect(partSource, isNotNull);
+ expect(partSource.isInSystemLibrary, isTrue);
+ }
+
+ void test_isInSystemLibrary_false() {
+ JavaFile file = FileUtilities2.createFile("/does/not/exist.dart");
+ FileBasedSource source = new FileBasedSource(file);
+ expect(source, isNotNull);
+ expect(source.fullName, file.getAbsolutePath());
+ expect(source.isInSystemLibrary, isFalse);
+ }
+
+ void test_issue14500() {
+ // see https://code.google.com/p/dart/issues/detail?id=14500
+ FileBasedSource source = new FileBasedSource(
+ FileUtilities2.createFile("/some/packages/foo:bar.dart"));
+ expect(source, isNotNull);
+ expect(source.exists(), isFalse);
+ }
+
+ void test_resolveRelative_dart_fileName() {
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source =
+ new FileBasedSource(file, parseUriWithException("dart:test"));
+ expect(source, isNotNull);
+ Uri relative = source.resolveRelativeUri(parseUriWithException("lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "dart:test/lib.dart");
+ }
+
+ void test_resolveRelative_dart_filePath() {
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source =
+ new FileBasedSource(file, parseUriWithException("dart:test"));
+ expect(source, isNotNull);
+ Uri relative =
+ source.resolveRelativeUri(parseUriWithException("c/lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "dart:test/c/lib.dart");
+ }
+
+ void test_resolveRelative_dart_filePathWithParent() {
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source = new FileBasedSource(
+ file, parseUriWithException("dart:test/b/test.dart"));
+ expect(source, isNotNull);
+ Uri relative =
+ source.resolveRelativeUri(parseUriWithException("../c/lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "dart:test/c/lib.dart");
+ }
+
+ void test_resolveRelative_file_fileName() {
+ if (OSUtilities.isWindows()) {
+ // On Windows, the URI that is produced includes a drive letter,
+ // which I believe is not consistent across all machines that might run
+ // this test.
+ return;
+ }
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source = new FileBasedSource(file);
+ expect(source, isNotNull);
+ Uri relative = source.resolveRelativeUri(parseUriWithException("lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "file:///a/b/lib.dart");
+ }
+
+ void test_resolveRelative_file_filePath() {
+ if (OSUtilities.isWindows()) {
+ // On Windows, the URI that is produced includes a drive letter,
+ // which I believe is not consistent across all machines that might run
+ // this test.
+ return;
+ }
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source = new FileBasedSource(file);
+ expect(source, isNotNull);
+ Uri relative =
+ source.resolveRelativeUri(parseUriWithException("c/lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "file:///a/b/c/lib.dart");
+ }
+
+ void test_resolveRelative_file_filePathWithParent() {
+ if (OSUtilities.isWindows()) {
+ // On Windows, the URI that is produced includes a drive letter, which I
+ // believe is not consistent across all machines that might run this test.
+ return;
+ }
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source = new FileBasedSource(file);
+ expect(source, isNotNull);
+ Uri relative =
+ source.resolveRelativeUri(parseUriWithException("../c/lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "file:///a/c/lib.dart");
+ }
+
+ void test_resolveRelative_package_fileName() {
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source =
+ new FileBasedSource(file, parseUriWithException("package:b/test.dart"));
+ expect(source, isNotNull);
+ Uri relative = source.resolveRelativeUri(parseUriWithException("lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "package:b/lib.dart");
+ }
+
+ void test_resolveRelative_package_fileNameWithoutPackageName() {
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source =
+ new FileBasedSource(file, parseUriWithException("package:test.dart"));
+ expect(source, isNotNull);
+ Uri relative = source.resolveRelativeUri(parseUriWithException("lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "package:lib.dart");
+ }
+
+ void test_resolveRelative_package_filePath() {
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source =
+ new FileBasedSource(file, parseUriWithException("package:b/test.dart"));
+ expect(source, isNotNull);
+ Uri relative =
+ source.resolveRelativeUri(parseUriWithException("c/lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "package:b/c/lib.dart");
+ }
+
+ void test_resolveRelative_package_filePathWithParent() {
+ JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
+ FileBasedSource source = new FileBasedSource(
+ file, parseUriWithException("package:a/b/test.dart"));
+ expect(source, isNotNull);
+ Uri relative =
+ source.resolveRelativeUri(parseUriWithException("../c/lib.dart"));
+ expect(relative, isNotNull);
+ expect(relative.toString(), "package:a/c/lib.dart");
+ }
+
+ void test_system() {
+ JavaFile file = FileUtilities2.createFile("/does/not/exist.dart");
+ FileBasedSource source =
+ new FileBasedSource(file, parseUriWithException("dart:core"));
+ expect(source, isNotNull);
+ expect(source.fullName, file.getAbsolutePath());
+ expect(source.isInSystemLibrary, isTrue);
+ }
+}
+
+@reflectiveTest
+class FileUriResolverTest {
+ void test_creation() {
+ expect(new FileUriResolver(), isNotNull);
+ }
+
+ void test_resolve_file() {
+ UriResolver resolver = new FileUriResolver();
+ Source result = resolver
+ .resolveAbsolute(parseUriWithException("file:/does/not/exist.dart"));
+ expect(result, isNotNull);
+ expect(result.fullName,
+ FileUtilities2.createFile("/does/not/exist.dart").getAbsolutePath());
+ }
+
+ void test_resolve_nonFile() {
+ UriResolver resolver = new FileUriResolver();
+ Source result =
+ resolver.resolveAbsolute(parseUriWithException("dart:core"));
+ expect(result, isNull);
+ }
+
+ void test_restore() {
+ UriResolver resolver = new FileUriResolver();
+ Uri uri = parseUriWithException('file:///foo/bar.dart');
+ Source source = resolver.resolveAbsolute(uri);
+ expect(source, isNotNull);
+ expect(resolver.restoreAbsolute(source), uri);
+ expect(
+ resolver.restoreAbsolute(
+ new NonExistingSource(source.fullName, null, null)),
+ uri);
+ }
+}
+
+@reflectiveTest
+class HtmlParserTest extends EngineTestCase {
+ /**
+ * The name of the 'script' tag in an HTML file.
+ */
+ static String _TAG_SCRIPT = "script";
+ void fail_parse_scriptWithComment() {
+ String scriptBody = r'''
+ /**
+ * <editable-label bind-value="dartAsignableValue">
+ * </editable-label>
+ */
+ class Foo {}''';
+ ht.HtmlUnit htmlUnit = parse("""
+<html>
+ <body>
+ <script type='application/dart'>
+$scriptBody
+ </script>
+ </body>
+</html>""");
+ _validate(htmlUnit, [
+ _t4("html", [
+ _t4("body", [
+ _t("script", _a(["type", "'application/dart'"]), scriptBody)
+ ])
+ ])
+ ]);
+ }
+
+ ht.HtmlUnit parse(String contents) {
+// TestSource source =
+// new TestSource.con1(FileUtilities2.createFile("/test.dart"), contents);
+ ht.AbstractScanner scanner = new ht.StringScanner(null, contents);
+ scanner.passThroughElements = <String>[_TAG_SCRIPT];
+ ht.Token token = scanner.tokenize();
+ LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ ht.HtmlUnit unit =
+ new ht.HtmlParser(null, errorListener, options).parse(token, lineInfo);
+ errorListener.assertNoErrors();
+ return unit;
+ }
+
+ void test_parse_attribute() {
+ ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
+ _validate(htmlUnit, [
+ _t4("html", [
+ _t("body", _a(["foo", "\"sdfsdf\""]), "")
+ ])
+ ]);
+ ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
+ ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
+ expect(bodyNode.attributes[0].text, "sdfsdf");
+ }
+
+ void test_parse_attribute_EOF() {
+ ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"");
+ _validate(htmlUnit, [
+ _t4("html", [
+ _t("body", _a(["foo", "\"sdfsdf\""]), "")
+ ])
+ ]);
+ }
+
+ void test_parse_attribute_EOF_missing_quote() {
+ ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsd");
+ _validate(htmlUnit, [
+ _t4("html", [
+ _t("body", _a(["foo", "\"sdfsd"]), "")
+ ])
+ ]);
+ ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
+ ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
+ expect(bodyNode.attributes[0].text, "sdfsd");
+ }
+
+ void test_parse_attribute_extra_quote() {
+ ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"\"></body></html>");
+ _validate(htmlUnit, [
+ _t4("html", [
+ _t("body", _a(["foo", "\"sdfsdf\""]), "")
+ ])
+ ]);
+ }
+
+ void test_parse_attribute_single_quote() {
+ ht.HtmlUnit htmlUnit = parse("<html><body foo='sdfsdf'></body></html>");
+ _validate(htmlUnit, [
+ _t4("html", [
+ _t("body", _a(["foo", "'sdfsdf'"]), "")
+ ])
+ ]);
+ ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
+ ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
+ expect(bodyNode.attributes[0].text, "sdfsdf");
+ }
+
+ void test_parse_comment_embedded() {
+ ht.HtmlUnit htmlUnit = parse("<html <!-- comment -->></html>");
+ _validate(htmlUnit, [_t3("html", "")]);
+ }
+
+ void test_parse_comment_first() {
+ ht.HtmlUnit htmlUnit = parse("<!-- comment --><html></html>");
+ _validate(htmlUnit, [_t3("html", "")]);
+ }
+
+ void test_parse_comment_in_content() {
+ ht.HtmlUnit htmlUnit = parse("<html><!-- comment --></html>");
+ _validate(htmlUnit, [_t3("html", "<!-- comment -->")]);
+ }
+
+ void test_parse_content() {
+ ht.HtmlUnit htmlUnit = parse("<html>\n<p a=\"b\">blat \n </p>\n</html>");
+ // ht.XmlTagNode.getContent() does not include whitespace
+ // between '<' and '>' at this time
+ _validate(htmlUnit, [
+ _t3("html", "\n<pa=\"b\">blat \n </p>\n", [
+ _t("p", _a(["a", "\"b\""]), "blat \n ")
+ ])
+ ]);
+ }
+
+ void test_parse_content_none() {
+ ht.HtmlUnit htmlUnit = parse("<html><p/>blat<p/></html>");
+ _validate(htmlUnit, [
+ _t3("html", "<p/>blat<p/>", [_t3("p", ""), _t3("p", "")])
+ ]);
+ }
+
+ void test_parse_declaration() {
+ ht.HtmlUnit htmlUnit = parse("<!DOCTYPE html>\n\n<html><p></p></html>");
+ _validate(htmlUnit, [
+ _t4("html", [_t3("p", "")])
+ ]);
+ }
+
+ void test_parse_directive() {
+ ht.HtmlUnit htmlUnit = parse("<?xml ?>\n\n<html><p></p></html>");
+ _validate(htmlUnit, [
+ _t4("html", [_t3("p", "")])
+ ]);
+ }
+
+ void test_parse_getAttribute() {
+ ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
+ ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
+ ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
+ expect(bodyNode.getAttribute("foo").text, "sdfsdf");
+ expect(bodyNode.getAttribute("bar"), null);
+ expect(bodyNode.getAttribute(null), null);
+ }
+
+ void test_parse_getAttributeText() {
+ ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
+ ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
+ ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
+ expect(bodyNode.getAttributeText("foo"), "sdfsdf");
+ expect(bodyNode.getAttributeText("bar"), null);
+ expect(bodyNode.getAttributeText(null), null);
+ }
+
+ void test_parse_headers() {
+ String code = r'''
+<html>
+ <body>
+ <h2>000</h2>
+ <div>
+ 111
+ </div>
+ </body>
+</html>''';
+ ht.HtmlUnit htmlUnit = parse(code);
+ _validate(htmlUnit, [
+ _t4("html", [
+ _t4("body", [_t3("h2", "000"), _t4("div")])
+ ])
+ ]);
+ }
+
+ void test_parse_script() {
+ ht.HtmlUnit htmlUnit =
+ parse("<html><script >here is <p> some</script></html>");
+ _validate(htmlUnit, [
+ _t4("html", [_t3("script", "here is <p> some")])
+ ]);
+ }
+
+ void test_parse_self_closing() {
+ ht.HtmlUnit htmlUnit = parse("<html>foo<br>bar</html>");
+ _validate(htmlUnit, [
+ _t3("html", "foo<br>bar", [_t3("br", "")])
+ ]);
+ }
+
+ void test_parse_self_closing_declaration() {
+ ht.HtmlUnit htmlUnit = parse("<!DOCTYPE html><html>foo</html>");
+ _validate(htmlUnit, [_t3("html", "foo")]);
+ }
+
+ XmlValidator_Attributes _a(List<String> keyValuePairs) =>
+ new XmlValidator_Attributes(keyValuePairs);
+ XmlValidator_Tag _t(
+ String tag, XmlValidator_Attributes attributes, String content,
+ [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
+ new XmlValidator_Tag(tag, attributes, content, children);
+ XmlValidator_Tag _t3(String tag, String content,
+ [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
+ new XmlValidator_Tag(
+ tag, new XmlValidator_Attributes(), content, children);
+ XmlValidator_Tag _t4(String tag,
+ [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
+ new XmlValidator_Tag(tag, new XmlValidator_Attributes(), null, children);
+ void _validate(ht.HtmlUnit htmlUnit, List<XmlValidator_Tag> expectedTags) {
+ XmlValidator validator = new XmlValidator();
+ validator.expectTags(expectedTags);
+ htmlUnit.accept(validator);
+ validator.assertValid();
+ }
+}
+
+@reflectiveTest
+class HtmlTagInfoBuilderTest extends HtmlParserTest {
+ void test_builder() {
+ HtmlTagInfoBuilder builder = new HtmlTagInfoBuilder();
+ ht.HtmlUnit unit = parse(r'''
+<html>
+ <body>
+ <div id="x"></div>
+ <p class='c'></p>
+ <div class='c'></div>
+ </body>
+</html>''');
+ unit.accept(builder);
+ HtmlTagInfo info = builder.getTagInfo();
+ expect(info, isNotNull);
+ List<String> allTags = info.allTags;
+ expect(allTags, hasLength(4));
+ expect(info.getTagWithId("x"), "div");
+ List<String> tagsWithClass = info.getTagsWithClass("c");
+ expect(tagsWithClass, hasLength(2));
+ }
+}
+
+@reflectiveTest
+class HtmlUnitBuilderTest extends EngineTestCase {
+ InternalAnalysisContext _context;
+ @override
+ void setUp() {
+ _context = AnalysisContextFactory.contextWithCore();
+ }
+
+ @override
+ void tearDown() {
+ _context = null;
+ super.tearDown();
+ }
+
+ void test_embedded_script() {
+ HtmlElementImpl element = _build(r'''
+<html>
+<script type="application/dart">foo=2;</script>
+</html>''');
+ _validate(element, [
+ _s(_l([_v("foo")]))
+ ]);
+ }
+
+ void test_embedded_script_no_content() {
+ HtmlElementImpl element = _build(r'''
+<html>
+<script type="application/dart"></script>
+</html>''');
+ _validate(element, [_s(_l())]);
+ }
+
+ void test_external_script() {
+ HtmlElementImpl element = _build(r'''
+<html>
+<script type="application/dart" src="other.dart"/>
+</html>''');
+ _validate(element, [_s2("other.dart")]);
+ }
+
+ void test_external_script_no_source() {
+ HtmlElementImpl element = _build(r'''
+<html>
+<script type="application/dart"/>
+</html>''');
+ _validate(element, [_s2(null)]);
+ }
+
+ void test_external_script_with_content() {
+ HtmlElementImpl element = _build(r'''
+<html>
+<script type="application/dart" src="other.dart">blat=2;</script>
+</html>''');
+ _validate(element, [_s2("other.dart")]);
+ }
+
+ void test_no_scripts() {
+ HtmlElementImpl element = _build(r'''
+<!DOCTYPE html>
+<html><p></p></html>''');
+ _validate(element, []);
+ }
+
+ void test_two_dart_scripts() {
+ HtmlElementImpl element = _build(r'''
+<html>
+<script type="application/dart">bar=2;</script>
+<script type="application/dart" src="other.dart"/>
+<script src="dart.js"/>
+</html>''');
+ _validate(element, [
+ _s(_l([_v("bar")])),
+ _s2("other.dart")
+ ]);
+ }
+
+ HtmlElementImpl _build(String contents) {
+ TestSource source = new TestSource(
+ FileUtilities2.createFile("/test.html").getAbsolutePath(), contents);
+ ChangeSet changeSet = new ChangeSet();
+ changeSet.addedSource(source);
+ _context.applyChanges(changeSet);
+ HtmlUnitBuilder builder = new HtmlUnitBuilder(_context);
+ return builder.buildHtmlElement(source, _context.parseHtmlUnit(source));
+ }
+
+ HtmlUnitBuilderTest_ExpectedLibrary _l(
+ [List<HtmlUnitBuilderTest_ExpectedVariable> expectedVariables =
+ HtmlUnitBuilderTest_ExpectedVariable.EMPTY_LIST]) =>
+ new HtmlUnitBuilderTest_ExpectedLibrary(this, expectedVariables);
+ _ExpectedScript _s(HtmlUnitBuilderTest_ExpectedLibrary expectedLibrary) =>
+ new _ExpectedScript.con1(expectedLibrary);
+ _ExpectedScript _s2(String scriptSourcePath) =>
+ new _ExpectedScript.con2(scriptSourcePath);
+ HtmlUnitBuilderTest_ExpectedVariable _v(String varName) =>
+ new HtmlUnitBuilderTest_ExpectedVariable(varName);
+ void _validate(
+ HtmlElementImpl element, List<_ExpectedScript> expectedScripts) {
+ expect(element.context, same(_context));
+ List<HtmlScriptElement> scripts = element.scripts;
+ expect(scripts, isNotNull);
+ expect(scripts, hasLength(expectedScripts.length));
+ for (int scriptIndex = 0; scriptIndex < scripts.length; scriptIndex++) {
+ expectedScripts[scriptIndex]._validate(scriptIndex, scripts[scriptIndex]);
+ }
+ }
+}
+
+class HtmlUnitBuilderTest_ExpectedLibrary {
+ final HtmlUnitBuilderTest HtmlUnitBuilderTest_this;
+ final List<HtmlUnitBuilderTest_ExpectedVariable> _expectedVariables;
+ HtmlUnitBuilderTest_ExpectedLibrary(this.HtmlUnitBuilderTest_this,
+ [this._expectedVariables =
+ HtmlUnitBuilderTest_ExpectedVariable.EMPTY_LIST]);
+ void _validate(int scriptIndex, EmbeddedHtmlScriptElementImpl script) {
+ LibraryElement library = script.scriptLibrary;
+ expect(library, isNotNull, reason: "script $scriptIndex");
+ expect(script.context, same(HtmlUnitBuilderTest_this._context),
+ reason: "script $scriptIndex");
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull, reason: "script $scriptIndex");
+ List<TopLevelVariableElement> variables = unit.topLevelVariables;
+ expect(variables, hasLength(_expectedVariables.length));
+ for (int index = 0; index < variables.length; index++) {
+ _expectedVariables[index].validate(scriptIndex, variables[index]);
+ }
+ expect(library.enclosingElement, same(script),
+ reason: "script $scriptIndex");
+ }
+}
+
+class HtmlUnitBuilderTest_ExpectedVariable {
+ static const List<HtmlUnitBuilderTest_ExpectedVariable> EMPTY_LIST =
+ const <HtmlUnitBuilderTest_ExpectedVariable>[];
+ final String _expectedName;
+ HtmlUnitBuilderTest_ExpectedVariable(this._expectedName);
+ void validate(int scriptIndex, TopLevelVariableElement variable) {
+ expect(variable, isNotNull, reason: "script $scriptIndex");
+ expect(variable.name, _expectedName, reason: "script $scriptIndex");
+ }
+}
+
+/**
+ * Instances of the class `HtmlWarningCodeTest` test the generation of HTML warning codes.
+ */
+@reflectiveTest
+class HtmlWarningCodeTest extends EngineTestCase {
+ /**
+ * The analysis context used to resolve the HTML files.
+ */
+ InternalAnalysisContext _context;
+
+ /**
+ * The contents of the 'test.html' file.
+ */
+ String _contents;
+
+ /**
+ * The list of reported errors.
+ */
+ List<AnalysisError> _errors;
+ @override
+ void setUp() {
+ _context = AnalysisContextFactory.contextWithCore();
+ }
+
+ @override
+ void tearDown() {
+ _context = null;
+ _contents = null;
+ _errors = null;
+ super.tearDown();
+ }
+
+ void test_invalidUri() {
+ _verify(
+ r'''
+<html>
+<script type='application/dart' src='ht:'/>
+</html>''',
+ [HtmlWarningCode.INVALID_URI]);
+ _assertErrorLocation2(_errors[0], "ht:");
+ }
+
+ void test_uriDoesNotExist() {
+ _verify(
+ r'''
+<html>
+<script type='application/dart' src='other.dart'/>
+</html>''',
+ [HtmlWarningCode.URI_DOES_NOT_EXIST]);
+ _assertErrorLocation2(_errors[0], "other.dart");
+ }
+
+ void _assertErrorLocation(
+ AnalysisError error, int expectedOffset, int expectedLength) {
+ expect(error.offset, expectedOffset, reason: error.toString());
+ expect(error.length, expectedLength, reason: error.toString());
+ }
+
+ void _assertErrorLocation2(AnalysisError error, String expectedString) {
+ _assertErrorLocation(
+ error, _contents.indexOf(expectedString), expectedString.length);
+ }
+
+ void _verify(String contents, List<ErrorCode> expectedErrorCodes) {
+ this._contents = contents;
+ TestSource source = new TestSource(
+ FileUtilities2.createFile("/test.html").getAbsolutePath(), contents);
+ ChangeSet changeSet = new ChangeSet();
+ changeSet.addedSource(source);
+ _context.applyChanges(changeSet);
+ HtmlUnitBuilder builder = new HtmlUnitBuilder(_context);
+ builder.buildHtmlElement(source, _context.parseHtmlUnit(source));
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ errorListener.addAll2(builder.errorListener);
+ errorListener.assertErrorsWithCodes(expectedErrorCodes);
+ _errors = errorListener.errors;
+ }
+}
+
+/**
+ * Instances of the class `MockDartSdk` implement a [DartSdk].
+ */
+class MockDartSdk implements DartSdk {
+ @override
+ AnalysisContext get context => null;
+
+ @override
+ List<SdkLibrary> get sdkLibraries => null;
+
+ @override
+ String get sdkVersion => null;
+
+ @override
+ List<String> get uris => null;
+
+ @override
+ Source fromFileUri(Uri uri) => null;
+
+ @override
+ SdkLibrary getSdkLibrary(String dartUri) => null;
+
+ @override
+ Source mapDartUri(String dartUri) => null;
+}
+
+@reflectiveTest
+class ReferenceFinderTest extends EngineTestCase {
+ DirectedGraph<ConstantEvaluationTarget> _referenceGraph;
+ VariableElement _head;
+ Element _tail;
+ @override
+ void setUp() {
+ _referenceGraph = new DirectedGraph<ConstantEvaluationTarget>();
+ _head = ElementFactory.topLevelVariableElement2("v1");
+ }
+
+ void test_visitSimpleIdentifier_const() {
+ _visitNode(_makeTailVariable("v2", true));
+ _assertOneArc(_tail);
+ }
+
+ void test_visitSimpleIdentifier_nonConst() {
+ _visitNode(_makeTailVariable("v2", false));
+ _assertOneArc(_tail);
+ }
+
+ void test_visitSuperConstructorInvocation_const() {
+ _visitNode(_makeTailSuperConstructorInvocation("A", true));
+ _assertOneArc(_tail);
+ }
+
+ void test_visitSuperConstructorInvocation_nonConst() {
+ _visitNode(_makeTailSuperConstructorInvocation("A", false));
+ _assertOneArc(_tail);
+ }
+
+ void test_visitSuperConstructorInvocation_unresolved() {
+ SuperConstructorInvocation superConstructorInvocation =
+ AstFactory.superConstructorInvocation();
+ _visitNode(superConstructorInvocation);
+ _assertNoArcs();
+ }
+
+ void _assertNoArcs() {
+ Set<ConstantEvaluationTarget> tails = _referenceGraph.getTails(_head);
+ expect(tails, hasLength(0));
+ }
+
+ void _assertOneArc(Element tail) {
+ Set<ConstantEvaluationTarget> tails = _referenceGraph.getTails(_head);
+ expect(tails, hasLength(1));
+ expect(tails.first, same(tail));
+ }
+
+ ReferenceFinder _createReferenceFinder(ConstantEvaluationTarget source) =>
+ new ReferenceFinder((ConstantEvaluationTarget dependency) {
+ _referenceGraph.addEdge(source, dependency);
+ });
+ SuperConstructorInvocation _makeTailSuperConstructorInvocation(
+ String name, bool isConst) {
+ List<ConstructorInitializer> initializers =
+ new List<ConstructorInitializer>();
+ ConstructorDeclaration constructorDeclaration = AstFactory
+ .constructorDeclaration(AstFactory.identifier3(name), null,
+ AstFactory.formalParameterList(), initializers);
+ if (isConst) {
+ constructorDeclaration.constKeyword = new KeywordToken(Keyword.CONST, 0);
+ }
+ ClassElementImpl classElement = ElementFactory.classElement2(name);
+ SuperConstructorInvocation superConstructorInvocation =
+ AstFactory.superConstructorInvocation();
+ ConstructorElementImpl constructorElement =
+ ElementFactory.constructorElement(classElement, name, isConst);
+ _tail = constructorElement;
+ superConstructorInvocation.staticElement = constructorElement;
+ return superConstructorInvocation;
+ }
+
+ SimpleIdentifier _makeTailVariable(String name, bool isConst) {
+ VariableDeclaration variableDeclaration =
+ AstFactory.variableDeclaration(name);
+ ConstLocalVariableElementImpl variableElement =
+ ElementFactory.constLocalVariableElement(name);
+ _tail = variableElement;
+ variableElement.const3 = isConst;
+ AstFactory.variableDeclarationList2(
+ isConst ? Keyword.CONST : Keyword.VAR, [variableDeclaration]);
+ SimpleIdentifier identifier = AstFactory.identifier3(name);
+ identifier.staticElement = variableElement;
+ return identifier;
+ }
+
+ void _visitNode(AstNode node) {
+ node.accept(_createReferenceFinder(_head));
+ }
+}
+
+@reflectiveTest
+class SDKLibrariesReaderTest extends EngineTestCase {
+ void test_readFrom_dart2js() {
+ LibraryMap libraryMap = new SdkLibrariesReader(true).readFromFile(
+ FileUtilities2.createFile("/libs.dart"),
+ r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'first' : const LibraryInfo(
+ 'first/first.dart',
+ category: 'First',
+ documented: true,
+ platforms: VM_PLATFORM,
+ dart2jsPath: 'first/first_dart2js.dart'),
+};''');
+ expect(libraryMap, isNotNull);
+ expect(libraryMap.size(), 1);
+ SdkLibrary first = libraryMap.getLibrary("dart:first");
+ expect(first, isNotNull);
+ expect(first.category, "First");
+ expect(first.path, "first/first_dart2js.dart");
+ expect(first.shortName, "dart:first");
+ expect(first.isDart2JsLibrary, false);
+ expect(first.isDocumented, true);
+ expect(first.isImplementation, false);
+ expect(first.isVmLibrary, true);
+ }
+
+ void test_readFrom_empty() {
+ LibraryMap libraryMap = new SdkLibrariesReader(false)
+ .readFromFile(FileUtilities2.createFile("/libs.dart"), "");
+ expect(libraryMap, isNotNull);
+ expect(libraryMap.size(), 0);
+ }
+
+ void test_readFrom_normal() {
+ LibraryMap libraryMap = new SdkLibrariesReader(false).readFromFile(
+ FileUtilities2.createFile("/libs.dart"),
+ r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'first' : const LibraryInfo(
+ 'first/first.dart',
+ category: 'First',
+ documented: true,
+ platforms: VM_PLATFORM),
+
+ 'second' : const LibraryInfo(
+ 'second/second.dart',
+ category: 'Second',
+ documented: false,
+ implementation: true,
+ platforms: 0),
+};''');
+ expect(libraryMap, isNotNull);
+ expect(libraryMap.size(), 2);
+ SdkLibrary first = libraryMap.getLibrary("dart:first");
+ expect(first, isNotNull);
+ expect(first.category, "First");
+ expect(first.path, "first/first.dart");
+ expect(first.shortName, "dart:first");
+ expect(first.isDart2JsLibrary, false);
+ expect(first.isDocumented, true);
+ expect(first.isImplementation, false);
+ expect(first.isVmLibrary, true);
+ SdkLibrary second = libraryMap.getLibrary("dart:second");
+ expect(second, isNotNull);
+ expect(second.category, "Second");
+ expect(second.path, "second/second.dart");
+ expect(second.shortName, "dart:second");
+ expect(second.isDart2JsLibrary, false);
+ expect(second.isDocumented, false);
+ expect(second.isImplementation, true);
+ expect(second.isVmLibrary, false);
+ }
+}
+
+@reflectiveTest
+class StringScannerTest extends AbstractScannerTest {
+ @override
+ ht.AbstractScanner newScanner(String input) {
+ return new ht.StringScanner(null, input);
+ }
+}
+
+/**
+ * Instances of the class `ToSourceVisitorTest`
+ */
+@reflectiveTest
+class ToSourceVisitorTest extends EngineTestCase {
+ void fail_visitHtmlScriptTagNode_attributes_content() {
+ _assertSource(
+ "<script type='application/dart'>f() {}</script>",
+ HtmlFactory.scriptTagWithContent(
+ "f() {}", [HtmlFactory.attribute("type", "'application/dart'")]));
+ }
+
+ void fail_visitHtmlScriptTagNode_noAttributes_content() {
+ _assertSource(
+ "<script>f() {}</script>", HtmlFactory.scriptTagWithContent("f() {}"));
+ }
+
+ void test_visitHtmlScriptTagNode_attributes_noContent() {
+ _assertSource(
+ "<script type='application/dart'/>",
+ HtmlFactory
+ .scriptTag([HtmlFactory.attribute("type", "'application/dart'")]));
+ }
+
+ void test_visitHtmlScriptTagNode_noAttributes_noContent() {
+ _assertSource("<script/>", HtmlFactory.scriptTag());
+ }
+
+ void test_visitHtmlUnit_empty() {
+ _assertSource("", new ht.HtmlUnit(null, new List<ht.XmlTagNode>(), null));
+ }
+
+ void test_visitHtmlUnit_nonEmpty() {
+ _assertSource(
+ "<html/>", new ht.HtmlUnit(null, [HtmlFactory.tagNode("html")], null));
+ }
+
+ void test_visitXmlAttributeNode() {
+ _assertSource("x=y", HtmlFactory.attribute("x", "y"));
+ }
+
+ /**
+ * Assert that a `ToSourceVisitor` will produce the expected source when visiting the given
+ * node.
+ *
+ * @param expectedSource the source string that the visitor is expected to produce
+ * @param node the AST node being visited to produce the actual source
+ */
+ void _assertSource(String expectedSource, ht.XmlNode node) {
+ PrintStringWriter writer = new PrintStringWriter();
+ node.accept(new ht.ToSourceVisitor(writer));
+ expect(writer.toString(), expectedSource);
+ }
+}
+
+@reflectiveTest
+class UriKindTest {
+ void test_fromEncoding() {
+ expect(UriKind.fromEncoding(0x64), same(UriKind.DART_URI));
+ expect(UriKind.fromEncoding(0x66), same(UriKind.FILE_URI));
+ expect(UriKind.fromEncoding(0x70), same(UriKind.PACKAGE_URI));
+ expect(UriKind.fromEncoding(0x58), same(null));
+ }
+
+ void test_getEncoding() {
+ expect(UriKind.DART_URI.encoding, 0x64);
+ expect(UriKind.FILE_URI.encoding, 0x66);
+ expect(UriKind.PACKAGE_URI.encoding, 0x70);
+ }
+}
+
+/**
+ * Instances of `XmlValidator` traverse an [XmlNode] structure and validate the node
+ * hierarchy.
+ */
+class XmlValidator extends ht.RecursiveXmlVisitor<Object> {
+ /**
+ * A list containing the errors found while traversing the AST structure.
+ */
+ List<String> _errors = new List<String>();
+ /**
+ * The tags to expect when visiting or `null` if tags should not be checked.
+ */
+ List<XmlValidator_Tag> _expectedTagsInOrderVisited;
+ /**
+ * The current index into the [expectedTagsInOrderVisited] array.
+ */
+ int _expectedTagsIndex = 0;
+ /**
+ * The key/value pairs to expect when visiting or `null` if attributes should not be
+ * checked.
+ */
+ List<String> _expectedAttributeKeyValuePairs;
+ /**
+ * The current index into the [expectedAttributeKeyValuePairs].
+ */
+ int _expectedAttributeIndex = 0;
+ /**
+ * Assert that no errors were found while traversing any of the AST structures that have been
+ * visited.
+ */
+ void assertValid() {
+ while (_expectedTagsIndex < _expectedTagsInOrderVisited.length) {
+ String expectedTag =
+ _expectedTagsInOrderVisited[_expectedTagsIndex++]._tag;
+ _errors.add("Expected to visit node with tag: $expectedTag");
+ }
+ if (!_errors.isEmpty) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write("Invalid XML structure:");
+ for (String message in _errors) {
+ buffer.writeln();
+ buffer.write(" ");
+ buffer.write(message);
+ }
+ fail(buffer.toString());
+ }
+ }
+
+ /**
+ * Set the tags to be expected when visiting
+ *
+ * @param expectedTags the expected tags
+ */
+ void expectTags(List<XmlValidator_Tag> expectedTags) {
+ // Flatten the hierarchy into expected order in which the tags are visited
+ List<XmlValidator_Tag> expected = new List<XmlValidator_Tag>();
+ _expectTags(expected, expectedTags);
+ this._expectedTagsInOrderVisited = expected;
+ }
+
+ @override
+ Object visitHtmlUnit(ht.HtmlUnit node) {
+ if (node.parent != null) {
+ _errors.add("HtmlUnit should not have a parent");
+ }
+ if (node.endToken.type != ht.TokenType.EOF) {
+ _errors.add("HtmlUnit end token should be of type EOF");
+ }
+ _validateNode(node);
+ return super.visitHtmlUnit(node);
+ }
+
+ @override
+ Object visitXmlAttributeNode(ht.XmlAttributeNode actual) {
+ if (actual.parent is! ht.XmlTagNode) {
+ _errors.add(
+ "Expected ${actual.runtimeType} to have parent of type XmlTagNode");
+ }
+ String actualName = actual.name;
+ String actualValue = actual.valueToken.lexeme;
+ if (_expectedAttributeIndex < _expectedAttributeKeyValuePairs.length) {
+ String expectedName =
+ _expectedAttributeKeyValuePairs[_expectedAttributeIndex];
+ if (expectedName != actualName) {
+ _errors.add(
+ "Expected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} to have name: $expectedName but found: $actualName");
+ }
+ String expectedValue =
+ _expectedAttributeKeyValuePairs[_expectedAttributeIndex + 1];
+ if (expectedValue != actualValue) {
+ _errors.add(
+ "Expected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} to have value: $expectedValue but found: $actualValue");
+ }
+ } else {
+ _errors.add(
+ "Unexpected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} name: $actualName value: $actualValue");
+ }
+ _expectedAttributeIndex += 2;
+ _validateNode(actual);
+ return super.visitXmlAttributeNode(actual);
+ }
+
+ @override
+ Object visitXmlTagNode(ht.XmlTagNode actual) {
+ if (!(actual.parent is ht.HtmlUnit || actual.parent is ht.XmlTagNode)) {
+ _errors.add(
+ "Expected ${actual.runtimeType} to have parent of type HtmlUnit or XmlTagNode");
+ }
+ if (_expectedTagsInOrderVisited != null) {
+ String actualTag = actual.tag;
+ if (_expectedTagsIndex < _expectedTagsInOrderVisited.length) {
+ XmlValidator_Tag expected =
+ _expectedTagsInOrderVisited[_expectedTagsIndex];
+ if (expected._tag != actualTag) {
+ _errors.add(
+ "Expected $_expectedTagsIndex tag: ${expected._tag} but found: $actualTag");
+ }
+ _expectedAttributeKeyValuePairs = expected._attributes._keyValuePairs;
+ int expectedAttributeCount =
+ _expectedAttributeKeyValuePairs.length ~/ 2;
+ int actualAttributeCount = actual.attributes.length;
+ if (expectedAttributeCount != actualAttributeCount) {
+ _errors.add(
+ "Expected $_expectedTagsIndex tag: ${expected._tag} to have $expectedAttributeCount attributes but found $actualAttributeCount");
+ }
+ _expectedAttributeIndex = 0;
+ _expectedTagsIndex++;
+ expect(actual.attributeEnd, isNotNull);
+ expect(actual.contentEnd, isNotNull);
+ int count = 0;
+ ht.Token token = actual.attributeEnd.next;
+ ht.Token lastToken = actual.contentEnd;
+ while (!identical(token, lastToken)) {
+ token = token.next;
+ if (++count > 1000) {
+ fail(
+ "Expected $_expectedTagsIndex tag: ${expected._tag} to have a sequence of tokens from getAttributeEnd() to getContentEnd()");
+ break;
+ }
+ }
+ if (actual.attributeEnd.type == ht.TokenType.GT) {
+ if (ht.HtmlParser.SELF_CLOSING.contains(actual.tag)) {
+ expect(actual.closingTag, isNull);
+ } else {
+ expect(actual.closingTag, isNotNull);
+ }
+ } else if (actual.attributeEnd.type == ht.TokenType.SLASH_GT) {
+ expect(actual.closingTag, isNull);
+ } else {
+ fail("Unexpected attribute end token: ${actual.attributeEnd.lexeme}");
+ }
+ if (expected._content != null && expected._content != actual.content) {
+ _errors.add(
+ "Expected $_expectedTagsIndex tag: ${expected._tag} to have content '${expected._content}' but found '${actual.content}'");
+ }
+ if (expected._children.length != actual.tagNodes.length) {
+ _errors.add(
+ "Expected $_expectedTagsIndex tag: ${expected._tag} to have ${expected._children.length} children but found ${actual.tagNodes.length}");
+ } else {
+ for (int index = 0; index < expected._children.length; index++) {
+ String expectedChildTag = expected._children[index]._tag;
+ String actualChildTag = actual.tagNodes[index].tag;
+ if (expectedChildTag != actualChildTag) {
+ _errors.add(
+ "Expected $_expectedTagsIndex tag: ${expected._tag} child $index to have tag: $expectedChildTag but found: $actualChildTag");
+ }
+ }
+ }
+ } else {
+ _errors.add("Visited unexpected tag: $actualTag");
+ }
+ }
+ _validateNode(actual);
+ return super.visitXmlTagNode(actual);
+ }
+
+ /**
+ * Append the specified tags to the array in depth first order
+ *
+ * @param expected the array to which the tags are added (not `null`)
+ * @param expectedTags the expected tags to be added (not `null`, contains no `null`s)
+ */
+ void _expectTags(
+ List<XmlValidator_Tag> expected, List<XmlValidator_Tag> expectedTags) {
+ for (XmlValidator_Tag tag in expectedTags) {
+ expected.add(tag);
+ _expectTags(expected, tag._children);
+ }
+ }
+
+ void _validateNode(ht.XmlNode node) {
+ if (node.beginToken == null) {
+ _errors.add("No begin token for ${node.runtimeType}");
+ }
+ if (node.endToken == null) {
+ _errors.add("No end token for ${node.runtimeType}");
+ }
+ int nodeStart = node.offset;
+ int nodeLength = node.length;
+ if (nodeStart < 0 || nodeLength < 0) {
+ _errors.add("No source info for ${node.runtimeType}");
+ }
+ ht.XmlNode parent = node.parent;
+ if (parent != null) {
+ int nodeEnd = nodeStart + nodeLength;
+ int parentStart = parent.offset;
+ int parentEnd = parentStart + parent.length;
+ if (nodeStart < parentStart) {
+ _errors.add(
+ "Invalid source start ($nodeStart) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
+ }
+ if (nodeEnd > parentEnd) {
+ _errors.add(
+ "Invalid source end ($nodeEnd) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
+ }
+ }
+ }
+}
+
+class XmlValidator_Attributes {
+ final List<String> _keyValuePairs;
+ XmlValidator_Attributes([this._keyValuePairs = StringUtilities.EMPTY_ARRAY]);
+}
+
+class XmlValidator_Tag {
+ static const List<XmlValidator_Tag> EMPTY_LIST = const <XmlValidator_Tag>[];
+ final String _tag;
+ final XmlValidator_Attributes _attributes;
+ final String _content;
+ final List<XmlValidator_Tag> _children;
+ XmlValidator_Tag(this._tag, this._attributes, this._content,
+ [this._children = EMPTY_LIST]);
+}
+
+class _ExpectedScript {
+ String _expectedExternalScriptName;
+ HtmlUnitBuilderTest_ExpectedLibrary _expectedLibrary;
+ _ExpectedScript.con1(HtmlUnitBuilderTest_ExpectedLibrary expectedLibrary) {
+ this._expectedExternalScriptName = null;
+ this._expectedLibrary = expectedLibrary;
+ }
+ _ExpectedScript.con2(String expectedExternalScriptPath) {
+ this._expectedExternalScriptName = expectedExternalScriptPath;
+ this._expectedLibrary = null;
+ }
+ void _validate(int scriptIndex, HtmlScriptElement script) {
+ if (_expectedLibrary != null) {
+ _validateEmbedded(scriptIndex, script);
+ } else {
+ _validateExternal(scriptIndex, script);
+ }
+ }
+
+ void _validateEmbedded(int scriptIndex, HtmlScriptElement script) {
+ if (script is! EmbeddedHtmlScriptElementImpl) {
+ fail(
+ "Expected script $scriptIndex to be embedded, but found ${script != null ? script.runtimeType : "null"}");
+ }
+ EmbeddedHtmlScriptElementImpl embeddedScript =
+ script as EmbeddedHtmlScriptElementImpl;
+ _expectedLibrary._validate(scriptIndex, embeddedScript);
+ }
+
+ void _validateExternal(int scriptIndex, HtmlScriptElement script) {
+ if (script is! ExternalHtmlScriptElementImpl) {
+ fail(
+ "Expected script $scriptIndex to be external with src=$_expectedExternalScriptName but found ${script != null ? script.runtimeType : "null"}");
+ }
+ ExternalHtmlScriptElementImpl externalScript =
+ script as ExternalHtmlScriptElementImpl;
+ Source scriptSource = externalScript.scriptSource;
+ if (_expectedExternalScriptName == null) {
+ expect(scriptSource, isNull, reason: "script $scriptIndex");
+ } else {
+ expect(scriptSource, isNotNull, reason: "script $scriptIndex");
+ String actualExternalScriptName = scriptSource.shortName;
+ expect(actualExternalScriptName, _expectedExternalScriptName,
+ reason: "script $scriptIndex");
+ }
+ }
+}
« no previous file with comments | « packages/analyzer/test/file_system/test_all.dart ('k') | packages/analyzer/test/generated/ast_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698