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

Unified Diff: pkg/front_end/test/precedence_info_test.dart

Issue 2758113002: fasta.PrecedenceInfo implement analyzer.TokenType (Closed)
Patch Set: merge Created 3 years, 9 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 | « pkg/front_end/lib/src/scanner/token.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/front_end/test/precedence_info_test.dart
diff --git a/pkg/front_end/test/precedence_info_test.dart b/pkg/front_end/test/precedence_info_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..56d2915640b7c469e4783e5506b3f2d0b9dee1ff
--- /dev/null
+++ b/pkg/front_end/test/precedence_info_test.dart
@@ -0,0 +1,458 @@
+// Copyright (c) 2017, 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.
+
+import 'package:front_end/src/fasta/scanner/precedence.dart';
+import 'package:front_end/src/fasta/scanner/string_scanner.dart';
+import 'package:front_end/src/fasta/scanner/token.dart' as fasta;
+import 'package:front_end/src/scanner/token.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PrecedenceInfoTest);
+ });
+}
+
+/// Assert that fasta PrecedenceInfo implements analyzer TokenType.
+@reflectiveTest
+class PrecedenceInfoTest {
+ var allTokenTypes = new Set<TokenType>.from(const [
+ TokenType.EOF,
+ TokenType.DOUBLE,
+ TokenType.HEXADECIMAL,
+ TokenType.IDENTIFIER,
+ TokenType.INT,
+ TokenType.KEYWORD,
+ TokenType.MULTI_LINE_COMMENT,
+ TokenType.SCRIPT_TAG,
+ TokenType.SINGLE_LINE_COMMENT,
+ TokenType.STRING,
+ TokenType.AMPERSAND,
+ TokenType.AMPERSAND_AMPERSAND,
+ TokenType.AMPERSAND_EQ,
+ TokenType.AT,
+ TokenType.BANG,
+ TokenType.BANG_EQ,
+ TokenType.BAR,
+ TokenType.BAR_BAR,
+ TokenType.BAR_EQ,
+ TokenType.COLON,
+ TokenType.COMMA,
+ TokenType.CARET,
+ TokenType.CARET_EQ,
+ TokenType.CLOSE_CURLY_BRACKET,
+ TokenType.CLOSE_PAREN,
+ TokenType.CLOSE_SQUARE_BRACKET,
+ TokenType.EQ,
+ TokenType.EQ_EQ,
+ TokenType.FUNCTION,
+ TokenType.GT,
+ TokenType.GT_EQ,
+ TokenType.GT_GT,
+ TokenType.GT_GT_EQ,
+ TokenType.HASH,
+ TokenType.INDEX,
+ TokenType.INDEX_EQ,
+ TokenType.LT,
+ TokenType.LT_EQ,
+ TokenType.LT_LT,
+ TokenType.LT_LT_EQ,
+ TokenType.MINUS,
+ TokenType.MINUS_EQ,
+ TokenType.MINUS_MINUS,
+ TokenType.OPEN_CURLY_BRACKET,
+ TokenType.OPEN_PAREN,
+ TokenType.OPEN_SQUARE_BRACKET,
+ TokenType.PERCENT,
+ TokenType.PERCENT_EQ,
+ TokenType.PERIOD,
+ TokenType.PERIOD_PERIOD,
+ TokenType.PLUS,
+ TokenType.PLUS_EQ,
+ TokenType.PLUS_PLUS,
+ TokenType.QUESTION,
+ TokenType.QUESTION_PERIOD,
+ TokenType.QUESTION_QUESTION,
+ TokenType.QUESTION_QUESTION_EQ,
+ TokenType.SEMICOLON,
+ TokenType.SLASH,
+ TokenType.SLASH_EQ,
+ TokenType.STAR,
+ TokenType.STAR_EQ,
+ TokenType.STRING_INTERPOLATION_EXPRESSION,
+ TokenType.STRING_INTERPOLATION_IDENTIFIER,
+ TokenType.TILDE,
+ TokenType.TILDE_SLASH,
+ TokenType.TILDE_SLASH_EQ,
+ TokenType.BACKPING,
+ TokenType.BACKSLASH,
+ TokenType.PERIOD_PERIOD_PERIOD,
+ TokenType.GENERIC_METHOD_TYPE_LIST,
+ TokenType.GENERIC_METHOD_TYPE_ASSIGN,
+
+ // These are not yet part of the language and not supported by fasta
+ //TokenType.AMPERSAND_AMPERSAND_EQ,
+ //TokenType.BAR_BAR_EQ,
+ ]);
+
+ void assertInfo(check(String source, fasta.Token token),
+ {bool includeLazyAssignmentOperators: true}) {
+ void assertLexeme(String source) {
+ if (source == null || source.isEmpty) return;
+ var scanner = new StringScanner(source, includeComments: true);
+ var token = scanner.tokenize();
+ check(source, token);
+ }
+
+ for (PrecedenceInfo info in PrecedenceInfo.all) {
+ assertLexeme(info.value);
+ }
+ for (TokenType tt in allTokenTypes) {
+ assertLexeme(tt.lexeme);
+ }
+ if (includeLazyAssignmentOperators) {
+ assertLexeme('&&=');
+ assertLexeme('||=');
+ }
+ }
+
+ void test_isOperator() {
+ var operatorLexemes = new Set<String>.from(const [
+ '&',
+ '&&',
+ '&&=',
+ '&=',
+ '!',
+ '!=',
+ '|',
+ '||',
+ '||=',
+ '|=',
+ '^',
+ '^=',
+ '=',
+ '==',
+ '>',
+ '>=',
+ '>>',
+ '>>=',
+ '[]',
+ '[]=',
+ '<',
+ '<=',
+ '<<',
+ '<<=',
+ '-',
+ '-=',
+ '--',
+ '%',
+ '%=',
+ '..',
+ '+',
+ '+=',
+ '++',
+ '?',
+ '?.',
+ '??',
+ '??=',
+ '/',
+ '/=',
+ '*',
+ '*=',
+ '~',
+ '~/',
+ '~/=',
+ ]);
+
+ assertInfo((String source, fasta.Token token) {
+ expect(token.isOperator, operatorLexemes.contains(source),
+ reason: source);
+ expect(token.type.isOperator, operatorLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isAdditiveOperator() {
+ var additiveLexemes = [
+ '-',
+ '+',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(token.type.isAdditiveOperator, additiveLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isAssignmentOperator() {
+ const assignmentLexemes = const [
+ '&=',
+ '|=',
+ '^=',
+ '=',
+ '>>=',
+ '<<=',
+ '-=',
+ '%=',
+ '+=',
+ '??=',
+ '/=',
+ '*=',
+ '~/=',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(
+ token.type.isAssignmentOperator, assignmentLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isAssociativeOperator() {
+ const associativeLexemes = const [
+ '&',
+ '&&',
+ '|',
+ '||',
+ '^',
+ '+',
+ '*',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(
+ token.type.isAssociativeOperator, associativeLexemes.contains(source),
+ reason: source);
+ }, includeLazyAssignmentOperators: false);
+ }
+
+ void test_isEqualityOperator() {
+ const equalityLexemes = const [
+ '!=',
+ '==',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(token.type.isEqualityOperator, equalityLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isIncrementOperator() {
+ const incrementLexemes = const [
+ '--',
+ '++',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(token.type.isIncrementOperator, incrementLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isMultiplicativeOperator() {
+ const multiplicativeLexemes = const [
+ '%',
+ '/',
+ '*',
+ '~/',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(token.type.isMultiplicativeOperator,
+ multiplicativeLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isRelationalOperator() {
+ const relationalLexemes = const [
+ '>',
+ '>=',
+ '<',
+ '<=',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(
+ token.type.isRelationalOperator, relationalLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isShiftOperator() {
+ const shiftLexemes = const [
+ '>>',
+ '<<',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(token.type.isShiftOperator, shiftLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isUnaryPostfixOperator() {
+ const unaryPostfixLexemes = const [
+ '--',
+ '(',
+ '[',
+ '.',
+ '++',
+ '?.',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(token.type.isUnaryPostfixOperator,
+ unaryPostfixLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isUnaryPrefixOperator() {
+ const unaryPrefixLexemes = const [
+ '!',
+ '--',
+ '++',
+ '~',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(
+ token.type.isUnaryPrefixOperator, unaryPrefixLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_isUserDefinableOperator() {
+ const userDefinableOperatorLexemes = const [
+ '&',
+ '|',
+ '^',
+ '==',
+ '>',
+ '>=',
+ '>>',
+ '[]',
+ '[]=',
+ '<',
+ '<=',
+ '<<',
+ '-',
+ '%',
+ '+',
+ '/',
+ '*',
+ '~',
+ '~/',
+ ];
+ assertInfo((String source, fasta.Token token) {
+ expect(token.type.isUserDefinableOperator,
+ userDefinableOperatorLexemes.contains(source),
+ reason: source);
+ expect(token.isUserDefinableOperator,
+ userDefinableOperatorLexemes.contains(source),
+ reason: source);
+ });
+ }
+
+ void test_name() {
+ void assertName(String source, String name, {int offset: 0}) {
+ if (source == null || source.isEmpty) return;
+ var scanner = new StringScanner(source, includeComments: true);
+ var token = scanner.tokenize();
+ while (token.offset < offset) {
+ token = token.next;
+ }
+ expect(token.type.name, name,
+ reason: 'source: $source\ntoken: ${token.lexeme}');
+ }
+
+ assertName('&', 'AMPERSAND');
+ assertName('&&', 'AMPERSAND_AMPERSAND');
+ assertName('&=', 'AMPERSAND_EQ');
+ assertName('@', 'AT');
+ assertName('!', 'BANG');
+ assertName('!=', 'BANG_EQ');
+ assertName('|', 'BAR');
+ assertName('||', 'BAR_BAR');
+ assertName('|=', 'BAR_EQ');
+ assertName(':', 'COLON');
+ assertName(',', 'COMMA');
+ assertName('^', 'CARET');
+ assertName('^=', 'CARET_EQ');
+ assertName('}', 'CLOSE_CURLY_BRACKET');
+ assertName(')', 'CLOSE_PAREN');
+ assertName(']', 'CLOSE_SQUARE_BRACKET');
+ assertName('=', 'EQ');
+ assertName('==', 'EQ_EQ');
+ assertName('=>', 'FUNCTION');
+ assertName('>', 'GT');
+ assertName('>=', 'GT_EQ');
+ assertName('>>', 'GT_GT');
+ assertName('>>=', 'GT_GT_EQ');
+ assertName('#', 'HASH');
+ assertName('[]', 'INDEX');
+ assertName('[]=', 'INDEX_EQ');
+ assertName('<', 'LT');
+ assertName('<=', 'LT_EQ');
+ assertName('<<', 'LT_LT');
+ assertName('<<=', 'LT_LT_EQ');
+ assertName('-', 'MINUS');
+ assertName('-=', 'MINUS_EQ');
+ assertName('--', 'MINUS_MINUS');
+ assertName('{', 'OPEN_CURLY_BRACKET');
+ assertName('(', 'OPEN_PAREN');
+ assertName('[', 'OPEN_SQUARE_BRACKET');
+ assertName('%', 'PERCENT');
+ assertName('%=', 'PERCENT_EQ');
+ assertName('.', 'PERIOD');
+ assertName('..', 'PERIOD_PERIOD');
+ assertName('+', 'PLUS');
+ assertName('+=', 'PLUS_EQ');
+ assertName('++', 'PLUS_PLUS');
+ assertName('?', 'QUESTION');
+ assertName('?.', 'QUESTION_PERIOD');
+ assertName('??', 'QUESTION_QUESTION');
+ assertName('??=', 'QUESTION_QUESTION_EQ');
+ assertName(';', 'SEMICOLON');
+ assertName('/', 'SLASH');
+ assertName('/=', 'SLASH_EQ');
+ assertName('*', 'STAR');
+ assertName('*=', 'STAR_EQ');
+ assertName('"\${', 'STRING_INTERPOLATION_EXPRESSION', offset: 1);
+ assertName('"\$', 'STRING_INTERPOLATION_IDENTIFIER', offset: 1);
+ assertName('~', 'TILDE');
+ assertName('~/', 'TILDE_SLASH');
+ assertName('~/=', 'TILDE_SLASH_EQ');
+ assertName('`', 'BACKPING');
+ assertName('\\', 'BACKSLASH');
+ assertName('...', 'PERIOD_PERIOD_PERIOD');
+ }
+
+ /// Assert precedence as per the Dart language spec
+ ///
+ /// Prefix "++" and "--" are excluded from the prefix (15) list
+ /// because they are interpreted as being in the postfix (16) list.
+ /// Leading "-" is excluded from the precedence 15 list
+ /// because it is interpreted as a minus token (precedence 13).
+ void test_precedence() {
+ const precedenceTable = const <int, List<String>>{
+ 16: const <String>['.', '?.', '++', '--', '[', '('],
+ 15: const <String>['!', '~'], // excluded '-', '++', '--'
+ 14: const <String>['*', '/', '~/', '%'],
+ 13: const <String>['+', '-'],
+ 12: const <String>['<<', '>>'],
+ 11: const <String>['&'],
+ 10: const <String>['^'],
+ 9: const <String>['|'],
+ 8: const <String>['<', '>', '<=', '>=', 'as', 'is', 'is!'],
+ 7: const <String>['==', '!='],
+ 6: const <String>['&&'],
+ 5: const <String>['||'],
+ 4: const <String>['??'],
+ 3: const <String>['? :'],
+ 2: const <String>['..'],
+ 1: const <String>['=', '*=', '/=', '+=', '-=', '&=', '^='],
+ };
+ precedenceTable.forEach((precedence, lexemes) {
+ for (String source in lexemes) {
+ var scanner = new StringScanner(source, includeComments: true);
+ var token = scanner.tokenize();
+ expect(token.type.precedence, precedence, reason: source);
+ }
+ });
+ }
+}
« no previous file with comments | « pkg/front_end/lib/src/scanner/token.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698