Class: Ruby2CExtension::Plugins::Warnings

Inherits:
Ruby2CExtension::Plugin show all
Defined in:
lib/ruby2cext/plugins/warnings.rb

Overview

TODO: Module.nesting, Module.constants, Kernel#autoload and Kernel#autoload?

Constant Summary collapse

CALL_TYPES =
[:vcall, :fcall, :call]
VCALL_WARNINGS =
{
	:binding => exp2,
	:local_variables => exp2,
	:callcc => exp,
}
FCALL_WARNINGS =
{
	:set_trace_func => exp,
	:eval => exp,
	:define_method => vis_exp % "method",
	:attr => vis_exp % "attribute",
	:attr_reader => vis_exp % "attribute(s)",
	:attr_writer => vis_exp % "attribute(s)",
	:attr_accessor => vis_exp % "attribute(s)",
	:instance_eval => exp,
	:module_eval => exp,
	:class_eval => exp,
}
CALL_WARNINGS =
{
	:arity => "will return -1 for all methods defined in compiled Ruby code",
	:instance_eval => exp,
	:module_eval => exp,
	:class_eval => exp,
}
BLOCK_PASS_WARNINGS =
{
	:define_method => true,
	:instance_eval => true,
	:module_eval => true,
	:class_eval => true,
}
NO_WARNING_WITH_ITER =
{
	:instance_eval => true,
	:module_eval => true,
	:class_eval => true,
}

Instance Attribute Summary

Attributes inherited from Ruby2CExtension::Plugin

#compiler

Instance Method Summary collapse

Methods inherited from Ruby2CExtension::Plugin

#global_c_code, #init_c_code

Constructor Details

#initialize(compiler) ⇒ Warnings

Returns a new instance of Warnings.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ruby2cext/plugins/warnings.rb', line 55

def initialize(compiler)
	super
	CALL_TYPES.each { |ct|
		ct_sym = "check_#{ct}".to_sym
		compiler.add_preprocessor(ct) { |cfun, node|
			send(ct_sym, node.last)
			node
		}
	}
	[:iter, :block_pass].each { |it|
		it_sym = "check_#{it}".to_sym
		compiler.add_preprocessor(it) { |cfun, node|
			if node.last[:iter] && CALL_TYPES.include?(node.last[:iter].first)
				send(it_sym, node.last[:iter])
			end
			node
		}
	}
end

Instance Method Details

#check_block_pass(iter_node) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/ruby2cext/plugins/warnings.rb', line 113

def check_block_pass(iter_node)
	mid = iter_node.last[:mid]
	if BLOCK_PASS_WARNINGS[mid]
		warn("#{mid} with block_pass: might not behave as expected", iter_node.last)
	else
		send("check_#{iter_node.first}", iter_node.last)
	end
end

#check_call(hash) ⇒ Object



100
101
102
103
104
# File 'lib/ruby2cext/plugins/warnings.rb', line 100

def check_call(hash)
	if (m = CALL_WARNINGS[hash[:mid]])
		warn("#{hash[:mid]}: #{m}", hash)
	end
end

#check_fcall(hash) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/ruby2cext/plugins/warnings.rb', line 90

def check_fcall(hash)
	if (m = FCALL_WARNINGS[hash[:mid]])
		warn("#{hash[:mid]}: #{m}", hash)
	else
		unless hash[:args]
			check_vcall(hash)
		end
	end
end

#check_iter(iter_node) ⇒ Object



106
107
108
109
110
111
# File 'lib/ruby2cext/plugins/warnings.rb', line 106

def check_iter(iter_node)
	mid = iter_node.last[:mid]
	unless NO_WARNING_WITH_ITER[mid]
		send("check_#{iter_node.first}", iter_node.last)
	end
end

#check_vcall(hash) ⇒ Object



84
85
86
87
88
# File 'lib/ruby2cext/plugins/warnings.rb', line 84

def check_vcall(hash)
	if (m = VCALL_WARNINGS[hash[:mid]])
		warn("#{hash[:mid]}: #{m}", hash)
	end
end

#warn(str, node_hash = {}) ⇒ Object



75
76
77
78
79
80
81
82
# File 'lib/ruby2cext/plugins/warnings.rb', line 75

def warn(str, node_hash = {})
	lstr = ""
	if (n = node_hash[:node])
		lstr << "#{n.file}:#{n.line}: "
	end
	lstr << "warning: " << str
	compiler.log(lstr, true)
end