Class: BiteScript::ClassBuilder
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#array? ⇒ Boolean
never generating an array.
-
#build_constructor(visibility, exceptions, *args) ⇒ Object
-
#build_method(name, visibility, static, exceptions, type, *args) ⇒ Object
-
#constructor(*params) ⇒ Object
-
#field(flags, name, type) ⇒ Object
-
#generate ⇒ Object
-
#initialize(file_builder, class_name, file_name, opts) ⇒ ClassBuilder
constructor
A new instance of ClassBuilder.
-
#interface? ⇒ Boolean
-
#java_method(name, *params) ⇒ Object
-
#macro(name, &b) ⇒ Object
-
#main(&b) ⇒ Object
-
#method(flags, name, signature, exceptions, &block) ⇒ Object
-
#name ⇒ Object
name for signature generation using the class being generated.
-
#new_method(modifiers, name, signature, exceptions) ⇒ Object
-
#primitive? ⇒ Boolean
never generating a primitive.
-
#start ⇒ Object
-
#static_init(&block) ⇒ Object
-
#stop ⇒ Object
-
#this ⇒ Object
-
#visit_annotation(*args) ⇒ Object
Methods included from Signature
ci, class_id, classname, path, sig, signature, tipath, type_insn_path
#annotate, #find_retention
Methods included from QuickTypes
#boolean, #byte, #char, #double, #float, #int, #long, #null, #object, #short, #string, #void
Methods included from Util
#type_from_dotted
Constructor Details
#initialize(file_builder, class_name, file_name, opts) ⇒ ClassBuilder
Returns a new instance of ClassBuilder.
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
|
# File 'lib/bitescript/builder.rb', line 248
def initialize(file_builder, class_name, file_name, opts)
@parent = file_builder
@class_name = class_name
@superclass = opts[:superclass] || Object
@interfaces = opts[:interfaces] || []
@interface = opts[:interface]
flags = Opcodes::ACC_SUPER
flags |= Opcodes::ACC_ABSTRACT if opts[:abstract]
if @interface
flags = Opcodes::ACC_INTERFACE | Opcodes::ACC_ABSTRACT
end
@class_writer = CustomClassWriter.new(
0 |
(BiteScript.compute_frames ? ClassWriter::COMPUTE_FRAMES : 0) |
(BiteScript.compute_maxs ? ClassWriter::COMPUTE_MAXS : 0),
&opts[:widen])
interface_paths = []
(@interfaces).each {|interface| interface_paths << path(interface)}
visibility = case (opts[:visibility] && opts[:visibility].to_sym)
when nil
Opcodes::ACC_PUBLIC
when :default
0
when :public
Opcodes::ACC_PUBLIC
when :private
Opcodes::ACC_PRIVATE
when :protected
Opcodes::ACC_PROTECTED
else
raise "Unknown visibility: #{opts[:visibility]}"
end
@class_writer.visit(BiteScript.bytecode_version, visibility | flags, class_name, nil, path(superclass), interface_paths.to_java(:string))
@class_writer.visit_source(file_name, nil)
@constructor = nil
@constructors = {}
@methods = {}
@imports = {}
@fields = {}
end
|
Instance Attribute Details
#class_name ⇒ Object
Returns the value of attribute class_name.
240
241
242
|
# File 'lib/bitescript/builder.rb', line 240
def class_name
@class_name
end
|
#constructors ⇒ Object
Returns the value of attribute constructors.
242
243
244
|
# File 'lib/bitescript/builder.rb', line 242
def constructors
@constructors
end
|
#fields ⇒ Object
Returns the value of attribute fields.
245
246
247
|
# File 'lib/bitescript/builder.rb', line 245
def fields
@fields
end
|
#imports ⇒ Object
Returns the value of attribute imports.
244
245
246
|
# File 'lib/bitescript/builder.rb', line 244
def imports
@imports
end
|
#interfaces ⇒ Object
Returns the value of attribute interfaces.
246
247
248
|
# File 'lib/bitescript/builder.rb', line 246
def interfaces
@interfaces
end
|
#methods ⇒ Object
Returns the value of attribute methods.
243
244
245
|
# File 'lib/bitescript/builder.rb', line 243
def methods
@methods
end
|
#superclass ⇒ Object
Returns the value of attribute superclass.
241
242
243
|
# File 'lib/bitescript/builder.rb', line 241
def superclass
@superclass
end
|
Instance Method Details
#array? ⇒ Boolean
never generating an array
458
459
460
|
# File 'lib/bitescript/builder.rb', line 458
def array?
false
end
|
#build_constructor(visibility, exceptions, *args) ⇒ Object
387
388
389
390
391
392
393
394
395
|
# File 'lib/bitescript/builder.rb', line 387
def build_constructor(visibility, exceptions, *args)
flags =
case visibility
when :public; Opcodes::ACC_PUBLIC
when :private; Opcodes::ACC_PRIVATE
when :protected; Opcodes::ACC_PROTECTED
end
@constructor = method(flags, "<init>", [nil, *args], exceptions)
end
|
#build_method(name, visibility, static, exceptions, type, *args) ⇒ Object
376
377
378
379
380
381
382
383
384
385
|
# File 'lib/bitescript/builder.rb', line 376
def build_method(name, visibility, static, exceptions, type, *args)
flags =
case visibility
when :public; Opcodes::ACC_PUBLIC
when :private; Opcodes::ACC_PRIVATE
when :protected; Opcodes::ACC_PROTECTED
end
flags |= Opcodes::ACC_STATIC if static
method(flags, name, [type, *args], exceptions)
end
|
#constructor(*params) ⇒ Object
438
439
440
|
# File 'lib/bitescript/builder.rb', line 438
def constructor(*params)
constructors[params] or raise NameError.new("failed to find constructor #{sig(params)} on #{self}")
end
|
#field(flags, name, type) ⇒ Object
447
448
449
450
|
# File 'lib/bitescript/builder.rb', line 447
def field(flags, name, type)
field = @class_writer.visit_field(flags, name, ci(type), nil, nil)
field.extend Annotatable
end
|
#generate ⇒ Object
311
312
313
314
315
316
317
318
319
320
321
|
# File 'lib/bitescript/builder.rb', line 311
def generate
bytes = @class_writer.to_byte_array
if ENV['BS_CHECK_CLASSES']
BiteScript::ASM::CheckClassAdapter.verify(
BiteScript::ASM::ClassReader.new(bytes),
JRuby.runtime.jruby_class_loader,
false,
java.io.PrintWriter.new(java.lang.System.out, true))
end
String.from_java_bytes(bytes)
end
|
#interface? ⇒ Boolean
442
443
444
445
|
# File 'lib/bitescript/builder.rb', line 442
def interface?
@interface
end
|
#java_method(name, *params) ⇒ Object
424
425
426
427
428
429
430
|
# File 'lib/bitescript/builder.rb', line 424
def java_method(name, *params)
if methods[name]
method = methods[name][params]
end
method or raise NameError.new("failed to find method #{name}#{sig(params)} on #{self}")
end
|
#macro(name, &b) ⇒ Object
484
485
486
|
# File 'lib/bitescript/builder.rb', line 484
def macro(name, &b)
MethodBuilder.send :define_method, name, &b
end
|
#main(&b) ⇒ Object
432
433
434
435
436
|
# File 'lib/bitescript/builder.rb', line 432
def main(&b)
raise "already defined main" if methods[name]
public_static_method "main", [], void, string[], &b
end
|
#method(flags, name, signature, exceptions, &block) ⇒ Object
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
|
# File 'lib/bitescript/builder.rb', line 397
def method(flags, name, signature, exceptions, &block)
flags |= Opcodes::ACC_ABSTRACT if interface?
mb = MethodBuilder.new(self, flags, name, exceptions, signature)
if name == "<init>"
constructors[signature[1..-1]] = mb
else
methods[name] ||= {}
methods[name][signature[1..-1]] = mb
end
mb.local 'this', self if (flags & Opcodes::ACC_STATIC) == 0
if block_given? && !interface?
mb.start
if block.arity == 1
block.call(mb)
else
mb.instance_eval(&block)
end
mb.stop
end
mb
end
|
#name ⇒ Object
name for signature generation using the class being generated
453
454
455
|
# File 'lib/bitescript/builder.rb', line 453
def name
@class_name
end
|
#new_method(modifiers, name, signature, exceptions) ⇒ Object
475
476
477
478
479
480
481
482
|
# File 'lib/bitescript/builder.rb', line 475
def new_method(modifiers, name, signature, exceptions)
exceptions ||= []
unless exceptions.kind_of?(Array)
raise ArgumentError, "Expected array of exceptions, got #{exceptions.inspect}"
end
exceptions = exceptions.map {|e| path(e)}
@class_writer.visit_method(modifiers, name, sig(*signature), nil, exceptions.to_java(:string))
end
|
#primitive? ⇒ Boolean
never generating a primitive
463
464
465
|
# File 'lib/bitescript/builder.rb', line 463
def primitive?
false
end
|
#start ⇒ Object
296
297
|
# File 'lib/bitescript/builder.rb', line 296
def start
end
|
#static_init(&block) ⇒ Object
372
373
374
|
# File 'lib/bitescript/builder.rb', line 372
def static_init(&block)
method(Opcodes::ACC_STATIC, "<clinit>", [void], [], &block)
end
|
#stop ⇒ Object
299
300
301
302
303
304
305
306
307
308
309
|
# File 'lib/bitescript/builder.rb', line 299
def stop
unless @constructor || @interface
method = public_constructor([])
method.start
method.aload 0
method.invokespecial @superclass, "<init>", [Void::TYPE]
method.returnvoid
method.stop
end
end
|
#this ⇒ Object
467
468
469
|
# File 'lib/bitescript/builder.rb', line 467
def this
self
end
|
#visit_annotation(*args) ⇒ Object
471
472
473
|
# File 'lib/bitescript/builder.rb', line 471
def visit_annotation(*args)
@class_writer.visit_annotation(*args)
end
|