зеркало из https://github.com/github/ruby.git
YARP resync (#8059)
This commit is contained in:
Родитель
47cb789332
Коммит
a02f5eb56a
|
@ -4427,7 +4427,7 @@ module YARP
|
|||
end
|
||||
end
|
||||
|
||||
# Represents a parentesized expression
|
||||
# Represents a parenthesized expression
|
||||
#
|
||||
# (10 + 34)
|
||||
# ^^^^^^^^^
|
||||
|
|
|
@ -426,9 +426,14 @@ class ErrorsTest < Test::Unit::TestCase
|
|||
expected = DefNode(
|
||||
Location(),
|
||||
nil,
|
||||
ParametersNode([], [], [], nil, [], nil, nil),
|
||||
ParametersNode([
|
||||
RequiredParameterNode(:A),
|
||||
RequiredParameterNode(:@a),
|
||||
RequiredParameterNode(:$A),
|
||||
RequiredParameterNode(:@@a),
|
||||
], [], [], nil, [], nil, nil),
|
||||
nil,
|
||||
[],
|
||||
[:A, :@a, :$A, :@@a],
|
||||
Location(),
|
||||
nil,
|
||||
Location(),
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "yarp_test_helper"
|
||||
|
||||
if RUBY_PLATFORM =~ /linux/
|
||||
#
|
||||
# examine a yarp dll or static archive for expected external symbols.
|
||||
# these tests only work on a linux system right now.
|
||||
#
|
||||
class LibrarySymbolsTest < Test::Unit::TestCase
|
||||
def setup
|
||||
super
|
||||
|
||||
@librubyparser_a = File.expand_path(File.join(__dir__, "..", "build", "librubyparser.a"))
|
||||
@librubyparser_so = File.expand_path(File.join(__dir__, "..", "build", "librubyparser.so"))
|
||||
@yarp_so = File.expand_path(File.join(__dir__, "..", "lib", "yarp.so"))
|
||||
end
|
||||
|
||||
# objdump runner and helpers
|
||||
def objdump(path)
|
||||
assert_path_exist(path)
|
||||
%x(objdump --section=.text --syms #{path}).split("\n")
|
||||
end
|
||||
|
||||
def global_objdump_symbols(path)
|
||||
objdump(path).select { |line| line[17] == "g" }
|
||||
end
|
||||
|
||||
def hidden_global_objdump_symbols(path)
|
||||
global_objdump_symbols(path).select { |line| line =~ / \.hidden / }
|
||||
end
|
||||
|
||||
def visible_global_objdump_symbols(path)
|
||||
global_objdump_symbols(path).reject { |line| line =~ / \.hidden / }
|
||||
end
|
||||
|
||||
# nm runner and helpers
|
||||
def nm(path)
|
||||
assert_path_exist(path)
|
||||
%x(nm #{path}).split("\n")
|
||||
end
|
||||
|
||||
def global_nm_symbols(path)
|
||||
nm(path).select { |line| line[17] == "T" }
|
||||
end
|
||||
|
||||
def local_nm_symbols(path)
|
||||
nm(path).select { |line| line[17] == "t" }
|
||||
end
|
||||
|
||||
# dig the symbol name out of each line. works for both `objdump` and `nm` output.
|
||||
def names(symbol_lines)
|
||||
symbol_lines.map { |line| line.split(/\s+/).last }
|
||||
end
|
||||
|
||||
#
|
||||
# static archive - librubyparser.a
|
||||
#
|
||||
def test_librubyparser_a_contains_nothing_globally_visible
|
||||
omit("librubyparser.a is not built") unless File.exist?(@librubyparser_a)
|
||||
|
||||
assert_empty(names(visible_global_objdump_symbols(@librubyparser_a)))
|
||||
end
|
||||
|
||||
def test_librubyparser_a_contains_hidden_yp_symbols
|
||||
omit("librubyparser.a is not built") unless File.exist?(@librubyparser_a)
|
||||
|
||||
names(hidden_global_objdump_symbols(@librubyparser_a)).tap do |symbols|
|
||||
assert_includes(symbols, "yp_parse")
|
||||
assert_includes(symbols, "yp_version")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# shared object - librubyparser.so
|
||||
#
|
||||
def test_librubyparser_so_exports_only_the_necessary_functions
|
||||
omit("librubyparser.so is not built") unless File.exist?(@librubyparser_so)
|
||||
|
||||
names(global_nm_symbols(@librubyparser_so)).tap do |symbols|
|
||||
assert_includes(symbols, "yp_parse")
|
||||
assert_includes(symbols, "yp_version")
|
||||
end
|
||||
names(local_nm_symbols(@librubyparser_so)).tap do |symbols|
|
||||
assert_includes(symbols, "yp_encoding_shift_jis_isupper_char")
|
||||
end
|
||||
# TODO: someone who uses this library needs to finish this test
|
||||
end
|
||||
|
||||
#
|
||||
# shared object - yarp.so
|
||||
#
|
||||
def test_yarp_so_exports_only_the_C_extension_init_function
|
||||
omit("yarp.so is not built") unless File.exist?(@yarp_so)
|
||||
|
||||
names(global_nm_symbols(@yarp_so)).tap do |symbols|
|
||||
assert_equal(["Init_yarp"], symbols)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,11 +12,9 @@
|
|||
#include <string.h>
|
||||
|
||||
// YP_EXPORTED_FUNCTION
|
||||
#if defined(YP_STATIC)
|
||||
# define YP_EXPORTED_FUNCTION
|
||||
#elif defined(_WIN32)
|
||||
#if defined(_WIN32)
|
||||
# define YP_EXPORTED_FUNCTION __declspec(dllexport) extern
|
||||
#else
|
||||
#elif defined(YP_EXPORT_SYMBOLS)
|
||||
# ifndef YP_EXPORTED_FUNCTION
|
||||
# ifndef RUBY_FUNC_EXPORTED
|
||||
# define YP_EXPORTED_FUNCTION __attribute__((__visibility__("default"))) extern
|
||||
|
@ -24,6 +22,8 @@
|
|||
# define YP_EXPORTED_FUNCTION RUBY_FUNC_EXPORTED
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# define YP_EXPORTED_FUNCTION
|
||||
#endif
|
||||
|
||||
// YP_ATTRIBUTE_UNUSED
|
||||
|
|
45
yarp/yarp.c
45
yarp/yarp.c
|
@ -3412,7 +3412,6 @@ yp_required_destructured_parameter_node_closing_set(yp_required_destructured_par
|
|||
// Allocate a new RequiredParameterNode node.
|
||||
static yp_required_parameter_node_t *
|
||||
yp_required_parameter_node_create(yp_parser_t *parser, const yp_token_t *token) {
|
||||
assert(token->type == YP_TOKEN_MISSING || token->type == YP_TOKEN_IDENTIFIER);
|
||||
yp_required_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_required_parameter_node_t);
|
||||
|
||||
*node = (yp_required_parameter_node_t) {
|
||||
|
@ -8244,8 +8243,27 @@ parse_parameters(
|
|||
}
|
||||
break;
|
||||
}
|
||||
case YP_TOKEN_IDENTIFIER: {
|
||||
case YP_TOKEN_CLASS_VARIABLE:
|
||||
case YP_TOKEN_IDENTIFIER:
|
||||
case YP_TOKEN_CONSTANT:
|
||||
case YP_TOKEN_INSTANCE_VARIABLE:
|
||||
case YP_TOKEN_GLOBAL_VARIABLE: {
|
||||
parser_lex(parser);
|
||||
switch (parser->previous.type) {
|
||||
case YP_TOKEN_CONSTANT:
|
||||
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a constant");
|
||||
break;
|
||||
case YP_TOKEN_INSTANCE_VARIABLE:
|
||||
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be an instance variable");
|
||||
break;
|
||||
case YP_TOKEN_GLOBAL_VARIABLE:
|
||||
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a global variable");
|
||||
break;
|
||||
case YP_TOKEN_CLASS_VARIABLE:
|
||||
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a class variable");
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (parser->current.type == YP_TOKEN_EQUAL) {
|
||||
update_parameter_state(parser, &parser->current, &order);
|
||||
|
@ -8387,22 +8405,6 @@ parse_parameters(
|
|||
yp_parameters_node_keyword_rest_set(params, param);
|
||||
break;
|
||||
}
|
||||
case YP_TOKEN_CONSTANT:
|
||||
parser_lex(parser);
|
||||
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a constant");
|
||||
break;
|
||||
case YP_TOKEN_INSTANCE_VARIABLE:
|
||||
parser_lex(parser);
|
||||
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be an instance variable");
|
||||
break;
|
||||
case YP_TOKEN_GLOBAL_VARIABLE:
|
||||
parser_lex(parser);
|
||||
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a global variable");
|
||||
break;
|
||||
case YP_TOKEN_CLASS_VARIABLE:
|
||||
parser_lex(parser);
|
||||
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a class variable");
|
||||
break;
|
||||
default:
|
||||
if (parser->previous.type == YP_TOKEN_COMMA) {
|
||||
if (allows_trailing_comma) {
|
||||
|
@ -8427,6 +8429,13 @@ parse_parameters(
|
|||
} while (looping && accept(parser, YP_TOKEN_COMMA));
|
||||
|
||||
yp_do_loop_stack_pop(parser);
|
||||
|
||||
// If we don't have any parameters, return `NULL` instead of an empty `ParametersNode`.
|
||||
if (params->base.location.start == params->base.location.end) {
|
||||
yp_node_destroy(parser, (yp_node_t *) params);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче