|
| 1 | +#!/usr/bin/env python |
| 2 | +# xfail-license |
| 3 | +# Copyright 2013 The Rust Project Developers. See the COPYRIGHT |
| 4 | +# file at the top-level directory of this distribution and at |
| 5 | +# http://rust-lang.org/COPYRIGHT. |
| 6 | +# |
| 7 | +# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| 8 | +# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| 9 | +# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
| 10 | +# option. This file may not be copied, modified, or distributed |
| 11 | +# except according to those terms. |
| 12 | + |
| 13 | +""" |
| 14 | +This script creates a pile of compile-fail tests check that all the |
| 15 | +derivings have spans that point to the fields, rather than the |
| 16 | +#[deriving(...)] line. |
| 17 | +
|
| 18 | +sample usage: src/etc/generate-deriving-span-tests.py |
| 19 | +""" |
| 20 | + |
| 21 | +import sys, os, datetime, stat |
| 22 | + |
| 23 | +TEST_DIR = os.path.abspath( |
| 24 | + os.path.join(os.path.dirname(__file__), '../test/compile-fail')) |
| 25 | + |
| 26 | +YEAR = datetime.datetime.now().year |
| 27 | + |
| 28 | +TEMPLATE = """// Copyright {year} The Rust Project Developers. See the COPYRIGHT |
| 29 | +// file at the top-level directory of this distribution and at |
| 30 | +// http://rust-lang.org/COPYRIGHT. |
| 31 | +// |
| 32 | +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| 33 | +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| 34 | +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
| 35 | +// option. This file may not be copied, modified, or distributed |
| 36 | +// except according to those terms. |
| 37 | +
|
| 38 | +// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' |
| 39 | +
|
| 40 | +#[feature(struct_variant)]; |
| 41 | +extern mod extra; |
| 42 | +
|
| 43 | +{error_deriving} |
| 44 | +struct Error; |
| 45 | +{code} |
| 46 | +fn main() {{}} |
| 47 | +""" |
| 48 | + |
| 49 | +ENUM_STRING = """ |
| 50 | +#[deriving({traits})] |
| 51 | +enum Enum {{ |
| 52 | + A( |
| 53 | + Error {errors} |
| 54 | + ) |
| 55 | +}} |
| 56 | +""" |
| 57 | +ENUM_STRUCT_VARIANT_STRING = """ |
| 58 | +#[deriving({traits})] |
| 59 | +enum Enum {{ |
| 60 | + A {{ |
| 61 | + x: Error {errors} |
| 62 | + }} |
| 63 | +}} |
| 64 | +""" |
| 65 | +STRUCT_STRING = """ |
| 66 | +#[deriving({traits})] |
| 67 | +struct Struct {{ |
| 68 | + x: Error {errors} |
| 69 | +}} |
| 70 | +""" |
| 71 | +STRUCT_TUPLE_STRING = """ |
| 72 | +#[deriving({traits})] |
| 73 | +struct Struct( |
| 74 | + Error {errors} |
| 75 | +); |
| 76 | +""" |
| 77 | + |
| 78 | +ENUM_TUPLE, ENUM_STRUCT, STRUCT_FIELDS, STRUCT_TUPLE = range(4) |
| 79 | + |
| 80 | +def create_test_case(type, trait, super_traits, number_of_errors): |
| 81 | + string = [ENUM_STRING, ENUM_STRUCT_VARIANT_STRING, STRUCT_STRING, STRUCT_TUPLE_STRING][type] |
| 82 | + all_traits = ','.join([trait] + super_traits) |
| 83 | + super_traits = ','.join(super_traits) |
| 84 | + error_deriving = '#[deriving(%s)]' % super_traits if super_traits else '' |
| 85 | + |
| 86 | + errors = '\n'.join('//~%s ERROR' % ('^' * n) for n in range(error_count)) |
| 87 | + code = string.format(traits = all_traits, errors = errors) |
| 88 | + return TEMPLATE.format(year = YEAR, error_deriving=error_deriving, code = code) |
| 89 | + |
| 90 | +def write_file(name, string): |
| 91 | + test_file = os.path.join(TEST_DIR, 'deriving-span-%s.rs' % name) |
| 92 | + |
| 93 | + # set write permission if file exists, so it can be changed |
| 94 | + if os.path.exists(test_file): |
| 95 | + os.chmod(test_file, stat.S_IWUSR) |
| 96 | + |
| 97 | + with open(test_file, 'wt') as f: |
| 98 | + f.write(string) |
| 99 | + |
| 100 | + # mark file read-only |
| 101 | + os.chmod(test_file, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) |
| 102 | + |
| 103 | + |
| 104 | + |
| 105 | +ENUM = 1 |
| 106 | +STRUCT = 2 |
| 107 | +ALL = STRUCT | ENUM |
| 108 | + |
| 109 | +traits = { |
| 110 | + 'Zero': (STRUCT, [], 1), |
| 111 | + 'Default': (STRUCT, [], 1), |
| 112 | + 'FromPrimitive': (0, [], 0), # only works for C-like enums |
| 113 | + |
| 114 | + 'Decodable': (0, [], 0), # FIXME: quoting gives horrible spans |
| 115 | + 'Encodable': (0, [], 0), # FIXME: quoting gives horrible spans |
| 116 | +} |
| 117 | + |
| 118 | +for (trait, supers, errs) in [('Rand', [], 1), |
| 119 | + ('Clone', [], 1), ('DeepClone', ['Clone'], 1), |
| 120 | + ('Eq', [], 2), ('Ord', [], 8), |
| 121 | + ('TotalEq', [], 2), ('TotalOrd', ['TotalEq'], 2)]: |
| 122 | + traits[trait] = (ALL, supers, errs) |
| 123 | + |
| 124 | +for (trait, (types, super_traits, error_count)) in traits.items(): |
| 125 | + mk = lambda ty: create_test_case(ty, trait, super_traits, error_count) |
| 126 | + if types & ENUM: |
| 127 | + write_file(trait + '-enum', mk(ENUM_TUPLE)) |
| 128 | + write_file(trait + '-enum-struct-variant', mk(ENUM_STRUCT)) |
| 129 | + if types & STRUCT: |
| 130 | + write_file(trait + '-struct', mk(STRUCT_FIELDS)) |
| 131 | + write_file(trait + '-tuple-struct', mk(STRUCT_TUPLE)) |
0 commit comments