Skip to content

Commit

Permalink
Showing 4 changed files with 96 additions and 2 deletions.
54 changes: 54 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
@@ -914,6 +914,60 @@ describe "macro methods" do
[TypeNode.new(program.string)] of ASTNode
end
end

it "executes ==" do
assert_macro("x", "{{x == Reference}}", "false") do |program|
[TypeNode.new(program.string)] of ASTNode
end
assert_macro("x", "{{x == String}}", "true") do |program|
[TypeNode.new(program.string)] of ASTNode
end
end

it "executes !=" do
assert_macro("x", "{{x != Reference}}", "true") do |program|
[TypeNode.new(program.string)] of ASTNode
end
assert_macro("x", "{{x != String}}", "false") do |program|
[TypeNode.new(program.string)] of ASTNode
end
end

it "executes <" do
assert_macro("x", "{{x < Reference}}", "true") do |program|
[TypeNode.new(program.string)] of ASTNode
end
assert_macro("x", "{{x < String}}", "false") do |program|
[TypeNode.new(program.string)] of ASTNode
end
end

it "executes <=" do
assert_macro("x", "{{x <= Reference}}", "true") do |program|
[TypeNode.new(program.string)] of ASTNode
end
assert_macro("x", "{{x <= String}}", "true") do |program|
[TypeNode.new(program.string)] of ASTNode
end
end

it "executes >" do
assert_macro("x", "{{x > Reference}}", "false") do |program|
[TypeNode.new(program.reference)] of ASTNode
end
assert_macro("x", "{{x > String}}", "true") do |program|
[TypeNode.new(program.reference)] of ASTNode
end
end

it "executes >=" do
assert_macro("x", "{{x >= Reference}}", "true") do |program|
[TypeNode.new(program.reference)] of ASTNode
end
assert_macro("x", "{{x >= String}}", "true") do |program|
[TypeNode.new(program.reference)] of ASTNode
end
end
end

describe "type declaration methods" do
18 changes: 18 additions & 0 deletions src/compiler/crystal/macros.cr
Original file line number Diff line number Diff line change
@@ -1202,6 +1202,24 @@ module Crystal::Macros
# methods by invoking `type.class.methods`.
def class : TypeNode
end

# Returns `true` if *other* is an ancestor of `self`.
def <(other : TypeNode) : BoolLiteral
end

# Returns `true` if `self` is the same as *other* or if
# *other* is an ancestor of `self`.
def <=(other : TypeNode) : BoolLiteral
end

# Returns `true` if `self` is an ancestor of *other*.
def >(other : TypeNode) : BoolLiteral
end

# Returns `true` if *other* is the same as `self` or if
# `self` is an ancestor of *other*.
def >=(other : TypeNode) : BoolLiteral
end
end

# A binary expression like `And` and `Or`.
20 changes: 20 additions & 0 deletions src/compiler/crystal/macros/methods.cr
Original file line number Diff line number Diff line change
@@ -1104,6 +1104,26 @@ module Crystal
end
when "class"
interpret_argless_method(method, args) { TypeNode.new(type.metaclass) }
when "<", "<=", ">", ">="
interpret_one_arg_method(method, args) do |arg|
unless arg.is_a?(TypeNode)
raise "TypeNode##{method} expects TypeNode, not #{arg.class_desc}"
end

self_type = self.type
other_type = arg.type
case method
when "<"
value = self_type != other_type && self_type.implements?(other_type)
when "<="
value = self_type.implements?(other_type)
when ">"
value = self_type != other_type && other_type.implements?(self_type)
else # ">="
value = other_type.implements?(self_type)
end
BoolLiteral.new(!!value)
end
else
super
end
6 changes: 4 additions & 2 deletions src/openssl/ssl/context.cr
Original file line number Diff line number Diff line change
@@ -84,14 +84,16 @@ abstract class OpenSSL::SSL::Context
#
# Required for OpenSSL <= 1.0.1 only.
protected def set_cert_verify_callback(hostname : String)
# Keep a reference so the GC doesn't collect it after sending it to C land
@hostname = hostname
LibSSL.ssl_ctx_set_cert_verify_callback(@handle, ->(x509_ctx, arg) {
if LibCrypto.x509_verify_cert(x509_ctx) != 0
cert = LibCrypto.x509_store_ctx_get_current_cert(x509_ctx)
HostnameValidation.validate_hostname(Box(String).unbox(arg), cert) == HostnameValidation::Result::MatchFound ? 1 : 0
HostnameValidation.validate_hostname(arg.as(String), cert) == HostnameValidation::Result::MatchFound ? 1 : 0
else
0
end
}, Box.box(hostname))
}, hostname.as(Void*))
end
end

0 comments on commit d4550f6

Please sign in to comment.