mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
Compare commits
4 commits
71d2e3f556
...
847c15e5ac
Author | SHA1 | Date | |
---|---|---|---|
![]() |
847c15e5ac | ||
![]() |
af87a302fa | ||
![]() |
b50327ad89 | ||
![]() |
d29470534f |
8 changed files with 96 additions and 23 deletions
30
.github/actions/cache-apt-packages-action/action.yml
vendored
Normal file
30
.github/actions/cache-apt-packages-action/action.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
name: 'Cache Apt Packages'
|
||||||
|
description: 'Cache all commonly used apt packages to speed up CI jobs'
|
||||||
|
|
||||||
|
# imagemagick : convert, mogrify
|
||||||
|
# xvfb : xvfb
|
||||||
|
# openimageio-tools : idiff
|
||||||
|
# libxcursor-dev libxi-dev : V gfx deps
|
||||||
|
# libgl1-mesa-dri : For headless rendering on the CI / software DRI driver (LIBGL_ALWAYS_SOFTWARE=true)
|
||||||
|
# freeglut3-dev : Fixes graphic apps compilation with tcc
|
||||||
|
# sdl2 : needed for Puzzle Vibes & Chocolate Doom
|
||||||
|
# libsodium-dev : needed for Gitly and C2V
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: 'composite'
|
||||||
|
steps:
|
||||||
|
- uses: awalsh128/cache-apt-pkgs-action@v1.5.3
|
||||||
|
with:
|
||||||
|
version: 1.0
|
||||||
|
packages: expect binutils postgresql sqlite3 clang valgrind \
|
||||||
|
imagemagick openimageio-tools xvfb xsel xclip \
|
||||||
|
libsodium-dev libpq-dev libssl-dev libsqlite3-dev \
|
||||||
|
libfreetype6-dev libxi-dev libxcursor-dev \
|
||||||
|
libgl-dev libxrandr-dev libasound2-dev \
|
||||||
|
libx11-dev freeglut3-dev mesa-common-dev libgl1-mesa-dev libgl1-mesa-dri \
|
||||||
|
libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev libsdl2-net-dev \
|
||||||
|
libpng-dev libsamplerate0-dev \
|
||||||
|
xfonts-75dpi xfonts-base
|
||||||
|
- name: Install common packages
|
||||||
|
run: echo "done installing packages"
|
||||||
|
shell: bash
|
|
@ -12,7 +12,7 @@ export VJOBS=1
|
||||||
show "Clone https://github.com/vlang/gui"
|
show "Clone https://github.com/vlang/gui"
|
||||||
v retry -- git clone --filter=blob:none --quiet https://github.com/vlang/gui ~/.vmodules/gui/
|
v retry -- git clone --filter=blob:none --quiet https://github.com/vlang/gui ~/.vmodules/gui/
|
||||||
show "Checkout last known good commit"
|
show "Checkout last known good commit"
|
||||||
git -C ~/.vmodules/gui/ checkout e5cc33fe816fef33d718cb1b91f66d6bd38fb4a4
|
git -C ~/.vmodules/gui/ checkout b4e3716b042ee6352efedff64c5b92cbf0e81ded
|
||||||
show "Check module for syntax and semantic errors"
|
show "Check module for syntax and semantic errors"
|
||||||
v -shared -check ~/.vmodules/gui
|
v -shared -check ~/.vmodules/gui
|
||||||
show "Execute Tests"
|
show "Execute Tests"
|
||||||
|
|
5
.github/workflows/puzzle_vibes_ci.yml
vendored
5
.github/workflows/puzzle_vibes_ci.yml
vendored
|
@ -33,10 +33,7 @@ jobs:
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- uses: awalsh128/cache-apt-pkgs-action@v1.5.3
|
- uses: ./.github/actions/cache-apt-packages-action
|
||||||
with:
|
|
||||||
packages: libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev
|
|
||||||
version: 1.0
|
|
||||||
|
|
||||||
- name: Build V
|
- name: Build V
|
||||||
run: make && ./v symlink
|
run: make && ./v symlink
|
||||||
|
|
|
@ -15,6 +15,6 @@ fn test_main() {
|
||||||
assert data.str() == 'Alias(SomeStruct{
|
assert data.str() == 'Alias(SomeStruct{
|
||||||
random_field_a: Option(none)
|
random_field_a: Option(none)
|
||||||
random_field_b: Option(none)
|
random_field_b: Option(none)
|
||||||
empty_field: Option(none)
|
empty_field: Option(Empty{})
|
||||||
})'
|
})'
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,21 +214,22 @@ fn (mut g Gen) gen_struct_equality_fn(left_type ast.Type) string {
|
||||||
field_type := g.unwrap(field.typ)
|
field_type := g.unwrap(field.typ)
|
||||||
field_name := c_name(field.name)
|
field_name := c_name(field.name)
|
||||||
|
|
||||||
left_arg := g.read_field(left_type, field_name, 'a')
|
mut left_arg := g.read_field(left_type, field_name, 'a')
|
||||||
right_arg := g.read_field(left_type, field_name, 'b')
|
mut right_arg := g.read_field(left_type, field_name, 'b')
|
||||||
|
|
||||||
if field.typ.has_flag(.option) {
|
if field.typ.has_flag(.option) {
|
||||||
fn_builder.write_string('((${left_arg}.state == ${right_arg}.state && ${right_arg}.state == 2) || ')
|
fn_builder.write_string('((${left_arg}.state == ${right_arg}.state && ${right_arg}.state == 2) || (${left_arg}.state != 2 && ${right_arg}.state != 2 && (')
|
||||||
}
|
}
|
||||||
if field_type.sym.kind == .string {
|
if field_type.sym.kind == .string {
|
||||||
if field.typ.has_flag(.option) {
|
if field.typ.has_flag(.option) {
|
||||||
left_arg_opt := g.read_opt_field(left_type, field_name, 'a', field.typ)
|
left_arg = g.read_opt_field(left_type, field_name, 'a', field.typ)
|
||||||
right_arg_opt := g.read_opt_field(left_type, field_name, 'b', field.typ)
|
right_arg = g.read_opt_field(left_type, field_name, 'b', field.typ)
|
||||||
fn_builder.write_string('(((${left_arg_opt}).len == (${right_arg_opt}).len && (${left_arg_opt}).len == 0) || fast_string_eq(${left_arg_opt}, ${right_arg_opt}))')
|
}
|
||||||
} else if field.typ.is_ptr() {
|
|
||||||
fn_builder.write_string('((${left_arg}->len == ${right_arg}->len && ${left_arg}->len == 0) || fast_string_eq(*(${left_arg}), *(${right_arg})))')
|
if field.typ.is_ptr() {
|
||||||
|
fn_builder.write_string('(${left_arg} == ${right_arg} || (${left_arg} != 0 && ${right_arg} != 0 && ((${left_arg})->len == (${right_arg})->len && (${left_arg})->len == 0) || fast_string_eq(*(${left_arg}), *(${right_arg}))))')
|
||||||
} else {
|
} else {
|
||||||
fn_builder.write_string('((${left_arg}.len == ${right_arg}.len && ${left_arg}.len == 0) || fast_string_eq(${left_arg}, ${right_arg}))')
|
fn_builder.write_string('(((${left_arg}).len == (${right_arg}).len && (${left_arg}).len == 0) || fast_string_eq(${left_arg}, ${right_arg}))')
|
||||||
}
|
}
|
||||||
} else if field_type.sym.kind == .sum_type && !field.typ.is_ptr() {
|
} else if field_type.sym.kind == .sum_type && !field.typ.is_ptr() {
|
||||||
eq_fn := g.gen_sumtype_equality_fn(field.typ)
|
eq_fn := g.gen_sumtype_equality_fn(field.typ)
|
||||||
|
@ -260,7 +261,7 @@ fn (mut g Gen) gen_struct_equality_fn(left_type ast.Type) string {
|
||||||
fn_builder.write_string('${eq_fn}_alias_eq(${left_arg}, ${right_arg})')
|
fn_builder.write_string('${eq_fn}_alias_eq(${left_arg}, ${right_arg})')
|
||||||
}
|
}
|
||||||
} else if field_type.sym.kind == .function && !field.typ.has_flag(.option) {
|
} else if field_type.sym.kind == .function && !field.typ.has_flag(.option) {
|
||||||
fn_builder.write_string('*((voidptr*)(${left_arg})) == *((voidptr*)(${right_arg}))')
|
fn_builder.write_string('((voidptr*)(${left_arg})) == ((voidptr*)(${right_arg}))')
|
||||||
} else if field_type.sym.kind == .interface
|
} else if field_type.sym.kind == .interface
|
||||||
&& (!field.typ.has_flag(.option) || !field.typ.is_ptr()) {
|
&& (!field.typ.has_flag(.option) || !field.typ.is_ptr()) {
|
||||||
ptr := if field.typ.is_ptr() { '*'.repeat(field.typ.nr_muls()) } else { '' }
|
ptr := if field.typ.is_ptr() { '*'.repeat(field.typ.nr_muls()) } else { '' }
|
||||||
|
@ -278,7 +279,7 @@ fn (mut g Gen) gen_struct_equality_fn(left_type ast.Type) string {
|
||||||
fn_builder.write_string('${left_arg} == ${right_arg}')
|
fn_builder.write_string('${left_arg} == ${right_arg}')
|
||||||
}
|
}
|
||||||
if field.typ.has_flag(.option) {
|
if field.typ.has_flag(.option) {
|
||||||
fn_builder.write_string(')')
|
fn_builder.write_string(')))')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -119,6 +119,19 @@ ${dec_fn_dec} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
')
|
')
|
||||||
|
|
||||||
|
if utyp.has_flag(.option) {
|
||||||
|
dec.writeln('\tif (cJSON_IsNull(root)) {')
|
||||||
|
dec.writeln('\t${result_name}_${ret_styp} ret;')
|
||||||
|
dec.writeln('\t_result_ok(&res, (${result_name}*)&ret, sizeof(res));')
|
||||||
|
dec.writeln('\treturn ret;')
|
||||||
|
dec.writeln('\t}')
|
||||||
|
|
||||||
|
base_type := utyp.clear_flag(.option)
|
||||||
|
base_type_str := g.styp(base_type)
|
||||||
|
dec.writeln('\t_option_ok(&(${base_type_str}[]){ ${g.type_default(base_type)} }, (${styp}*)&res, sizeof(${base_type_str}));\n')
|
||||||
|
}
|
||||||
|
|
||||||
extern_str := if g.pref.parallel_cc { 'extern ' } else { '' }
|
extern_str := if g.pref.parallel_cc { 'extern ' } else { '' }
|
||||||
g.json_forward_decls.writeln('${extern_str}${dec_fn_dec};')
|
g.json_forward_decls.writeln('${extern_str}${dec_fn_dec};')
|
||||||
// Codegen encoder
|
// Codegen encoder
|
||||||
|
|
26
vlib/v/tests/structs/struct_option_field_comparison_test.v
Normal file
26
vlib/v/tests/structs/struct_option_field_comparison_test.v
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
pub struct SomeStruct {
|
||||||
|
pub mut:
|
||||||
|
test ?string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MyStruct {
|
||||||
|
pub mut:
|
||||||
|
id string
|
||||||
|
result ?SomeStruct
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_struct_with_option_fields_inequality() {
|
||||||
|
a := MyStruct{
|
||||||
|
id: 'some id'
|
||||||
|
result: none
|
||||||
|
}
|
||||||
|
b := MyStruct{
|
||||||
|
id: 'some id'
|
||||||
|
result: SomeStruct{}
|
||||||
|
}
|
||||||
|
dump(a)
|
||||||
|
dump(b)
|
||||||
|
dump(a == b)
|
||||||
|
dump(a != b)
|
||||||
|
assert a != b
|
||||||
|
}
|
|
@ -252,13 +252,19 @@ pub fn (mut t TypeResolver) get_type(node ast.Expr) ast.Type {
|
||||||
return node.typ
|
return node.typ
|
||||||
} else if node is ast.ComptimeCall {
|
} else if node is ast.ComptimeCall {
|
||||||
method_name := t.info.comptime_for_method.name
|
method_name := t.info.comptime_for_method.name
|
||||||
left_sym := t.table.sym(t.resolver.unwrap_generic(node.left_type))
|
left_type := t.resolver.unwrap_generic(node.left_type)
|
||||||
f := left_sym.find_method(method_name) or {
|
left_sym := t.table.sym(left_type)
|
||||||
|
if f := left_sym.find_method(method_name) {
|
||||||
|
return f.return_type
|
||||||
|
} else if left_sym.kind == .alias {
|
||||||
|
f := t.table.final_sym(left_type).find_method(method_name) or {
|
||||||
t.error('could not find method `${method_name}` on compile-time resolution',
|
t.error('could not find method `${method_name}` on compile-time resolution',
|
||||||
node.method_pos)
|
node.method_pos)
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
return f.return_type
|
return f.return_type
|
||||||
|
}
|
||||||
|
return ast.void_type
|
||||||
} else if node is ast.IndexExpr && t.info.is_comptime(node.left) {
|
} else if node is ast.IndexExpr && t.info.is_comptime(node.left) {
|
||||||
nltype := t.get_type(node.left)
|
nltype := t.get_type(node.left)
|
||||||
nltype_unwrapped := t.resolver.unwrap_generic(nltype)
|
nltype_unwrapped := t.resolver.unwrap_generic(nltype)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue