mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
244 lines
7.3 KiB
Python
Executable File
244 lines
7.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright (C) 2013 Google Inc. All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met:
|
|
#
|
|
# * Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# * Redistributions in binary form must reproduce the above
|
|
# copyright notice, this list of conditions and the following disclaimer
|
|
# in the documentation and/or other materials provided with the
|
|
# distribution.
|
|
# * Neither the name of Google Inc. nor the names of its
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
import tempfile
|
|
import unittest
|
|
|
|
from make_token_matcher import BadInput, CaseLineProcessor, MainLineProcessor, Optimizer, process_file, SwitchCase, SwitchLineProcessor
|
|
|
|
|
|
class OptimizerTest(unittest.TestCase):
|
|
def test_nonalphabetic(self):
|
|
optimizer = Optimizer(None, None, None)
|
|
self.assertRaises(
|
|
BadInput,
|
|
optimizer.inspect_array,
|
|
[SwitchCase('-', None), SwitchCase('x', None)],
|
|
[0])
|
|
|
|
|
|
class MainLineProcessorTest(unittest.TestCase):
|
|
def test_switch(self):
|
|
processor = MainLineProcessor(None)
|
|
switchLineProcessor = processor.process_line('SWITCH(array, length) {')
|
|
self.assertIsInstance(switchLineProcessor, SwitchLineProcessor)
|
|
self.assertEquals('array', switchLineProcessor.array_variable)
|
|
self.assertEquals('length', switchLineProcessor.length_variable)
|
|
|
|
|
|
class SwitchLineProcessorTest(unittest.TestCase):
|
|
def test_case(self):
|
|
processor = SwitchLineProcessor(None, None, None, None)
|
|
caseLineProcessor = processor.process_line('CASE("identifier") {')
|
|
self.assertIsInstance(caseLineProcessor, CaseLineProcessor)
|
|
self.assertEquals('identifier', caseLineProcessor.identifier)
|
|
|
|
def test_unexpected(self):
|
|
processor = SwitchLineProcessor(None, None, None, None)
|
|
self.assertRaises(
|
|
BadInput,
|
|
processor.process_line,
|
|
'unexpected')
|
|
|
|
def test_repeated(self):
|
|
processor = SwitchLineProcessor(None, None, None, None)
|
|
processor.process_line('CASE("x") {').process_line('}')
|
|
caseLineProcessor = processor.process_line('CASE("x") {')
|
|
self.assertRaises(
|
|
BadInput,
|
|
caseLineProcessor.process_line,
|
|
'}')
|
|
|
|
|
|
class CaseLineProcessorTest(unittest.TestCase):
|
|
def test_break(self):
|
|
processor = CaseLineProcessor(None, None, None)
|
|
self.assertRaises(
|
|
BadInput,
|
|
processor.process_line,
|
|
'break;')
|
|
|
|
|
|
class ProcessFileTest(unittest.TestCase):
|
|
SOURCE_SMALL = """
|
|
SWITCH(p, q) {
|
|
CASE("a(") {
|
|
X;
|
|
}
|
|
CASE("b(") {
|
|
Y;
|
|
}
|
|
}
|
|
"""
|
|
|
|
EXPECTED_SMALL = """
|
|
if (LIKELY(q == 2)) {
|
|
if (LIKELY(p[1] == '(')) {
|
|
if ((p[0] | 0x20) == 'a') {
|
|
X;
|
|
} else if (LIKELY((p[0] | 0x20) == 'b')) {
|
|
Y;
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
SOURCE_MEDIUM = """
|
|
SWITCH (p, q) {
|
|
CASE ("ab") {
|
|
X;
|
|
}
|
|
CASE ("cd") {
|
|
Y;
|
|
}
|
|
CASE ("ed") {
|
|
Z;
|
|
}
|
|
}
|
|
"""
|
|
|
|
EXPECTED_MEDIUM = """
|
|
if (LIKELY(q == 2)) {
|
|
if ((p[1] | 0x20) == 'b') {
|
|
if (LIKELY((p[0] | 0x20) == 'a')) {
|
|
X;
|
|
}
|
|
} else if (LIKELY((p[1] | 0x20) == 'd')) {
|
|
if ((p[0] | 0x20) == 'c') {
|
|
Y;
|
|
} else if (LIKELY((p[0] | 0x20) == 'e')) {
|
|
Z;
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
SOURCE_LARGE = """
|
|
prefix;
|
|
SWITCH(p, q) {
|
|
CASE("hij") {
|
|
R;
|
|
}
|
|
CASE("efg") {
|
|
S;
|
|
}
|
|
CASE("c-") {
|
|
T;
|
|
}
|
|
CASE("klm") {
|
|
U;
|
|
}
|
|
|
|
CASE("d-") {
|
|
V;
|
|
}
|
|
CASE("a") {
|
|
W;
|
|
X;
|
|
}
|
|
CASE("b-") {
|
|
Y;
|
|
Z;
|
|
}
|
|
}
|
|
suffix;
|
|
"""
|
|
|
|
EXPECTED_LARGE = """
|
|
prefix;
|
|
switch (q) {
|
|
case 1: {
|
|
if (LIKELY((p[0] | 0x20) == 'a')) {
|
|
W;
|
|
X;
|
|
}
|
|
} break;
|
|
case 2: {
|
|
if (LIKELY(p[1] == '-')) {
|
|
switch ((p[0] | 0x20)) {
|
|
case 'b': {
|
|
Y;
|
|
Z;
|
|
} break;
|
|
case 'c': {
|
|
T;
|
|
} break;
|
|
case 'd': {
|
|
V;
|
|
} break;
|
|
}
|
|
}
|
|
} break;
|
|
case 3: {
|
|
switch ((p[0] | 0x20)) {
|
|
case 'e': {
|
|
if (LIKELY((p[1] | 0x20) == 'f' && (p[2] | 0x20) == 'g')) {
|
|
S;
|
|
}
|
|
} break;
|
|
case 'h': {
|
|
if (LIKELY((p[1] | 0x20) == 'i' && (p[2] | 0x20) == 'j')) {
|
|
R;
|
|
}
|
|
} break;
|
|
case 'k': {
|
|
if (LIKELY((p[1] | 0x20) == 'l' && (p[2] | 0x20) == 'm')) {
|
|
U;
|
|
}
|
|
} break;
|
|
}
|
|
} break;
|
|
}
|
|
suffix;
|
|
"""
|
|
|
|
def validate(self, source, expected):
|
|
with tempfile.NamedTemporaryFile() as input_file:
|
|
with tempfile.NamedTemporaryFile() as generated_file:
|
|
input_file.write(source)
|
|
input_file.flush()
|
|
process_file(input_file.name, generated_file.name)
|
|
# Our code generation does not yet implement pretty indentation.
|
|
actual = generated_file.read().replace(' ', '')
|
|
expected = expected.replace(' ', '')
|
|
self.assertEquals(actual, expected)
|
|
|
|
def test_small(self):
|
|
self.validate(ProcessFileTest.SOURCE_SMALL, ProcessFileTest.EXPECTED_SMALL)
|
|
|
|
def test_medium(self):
|
|
self.validate(ProcessFileTest.SOURCE_MEDIUM, ProcessFileTest.EXPECTED_MEDIUM)
|
|
|
|
def test_large(self):
|
|
self.validate(ProcessFileTest.SOURCE_LARGE, ProcessFileTest.EXPECTED_LARGE)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|