bitescript 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,649 @@
1
+ require 'jruby'
2
+
3
+ module BiteScript::ASM
4
+ class EnumValue
5
+ attr_reader :declaring_type, :name
6
+
7
+ def initialize(declaring_type, name)
8
+ @declaring_type = declaring_type
9
+ @name = name
10
+ end
11
+ end
12
+
13
+ class AnnotationMirror
14
+ attr_reader :type, :parent
15
+ def initialize(type, parent=nil)
16
+ @type = type
17
+ @parent = parent
18
+ @values = {}
19
+ end
20
+
21
+ def value
22
+ @values['value']
23
+ end
24
+
25
+ def value=(value)
26
+ @values['value'] = value
27
+ end
28
+
29
+ def [](name)
30
+ @values[name]
31
+ end
32
+
33
+ def []=(name, value)
34
+ @values[name] = value
35
+ end
36
+
37
+ def inspect
38
+ unless @values.empty?
39
+ values = []
40
+ @values.each do |k, v|
41
+ values << "#{k}=#{inspect_value(v)}"
42
+ end
43
+ values = "(#{values.join ', '})"
44
+ end
45
+ "@#{type.class_name}#{values}\n"
46
+ end
47
+
48
+ def inspect_value(v)
49
+ case v
50
+ when Type
51
+ v.class_name + ".class"
52
+ when Array
53
+ "{#{v.map{|x| inspect_value(x)}.join(', ')}}"
54
+ when EnumValue
55
+ "#{v.declaring_type.class_name}.#{v.name}"
56
+ else
57
+ v.inspect
58
+ end
59
+ end
60
+
61
+ class Builder
62
+ class ValueArray
63
+ attr_reader :parent
64
+ def initialize(annotation, array)
65
+ @parent = annotation
66
+ @array = array
67
+ end
68
+
69
+ def []=(name, value)
70
+ @array << value
71
+ end
72
+ end
73
+
74
+ include BiteScript::ASM::AnnotationVisitor
75
+
76
+ attr_reader :annotation
77
+ def initialize(desc, visible)
78
+ @current = @annotation = AnnotationMirror.new(Type.getType(desc))
79
+ end
80
+
81
+
82
+ def visit(name, value)
83
+ case value
84
+ when ArrayJavaProxy
85
+ visitArray(name)
86
+ value.each {|x| visit(name, x)}
87
+ visitEnd
88
+ else
89
+ @current[name] = value
90
+ end
91
+ end
92
+
93
+ def visitAnnotation(name, desc)
94
+ child = AnnotationMirror.new(Type.getType(desc), @current)
95
+ @current[name] = child
96
+ @current = child
97
+ self
98
+ end
99
+
100
+ def visitArray(name)
101
+ array = @current[name] = []
102
+ @current = ValueArray.new(@current, array)
103
+ self
104
+ end
105
+
106
+ def visitEnum(name, desc, value)
107
+ @current[name] = EnumValue.new(Type.getType(desc), value)
108
+ end
109
+
110
+ def visitEnd
111
+ @current = @current.parent
112
+ end
113
+ end
114
+ end
115
+
116
+ module Annotated
117
+ def annotations
118
+ @annotations ||= {}
119
+ end
120
+
121
+ def addAnnotation(annotation)
122
+ annotations[annotation.type.class_name] = annotation
123
+ end
124
+
125
+ def getDeclaredAnnotation(name)
126
+ annotations[name]
127
+ end
128
+
129
+ def declaredAnnotations
130
+ annotations.values
131
+ end
132
+
133
+ def inspect_annotations
134
+ declaredAnnotations.map {|a| a.inspect}.join('')
135
+ end
136
+ end
137
+
138
+ module Modifiers
139
+ attr_accessor :flags
140
+ def self.add_modifier(name)
141
+ class_eval <<-EOF
142
+ def #{name.downcase}?
143
+ (flags & Opcodes.ACC_#{name.upcase}) != 0
144
+ end
145
+ EOF
146
+ end
147
+ %w(annotation bridge deprecated enum interface synthetic).each do |name|
148
+ add_modifier(name)
149
+ end
150
+ code = ''
151
+ %w(Public Private Protected Final Native Abstract
152
+ Static Strict Synchronized Transient Volatile).each do |name|
153
+ add_modifier(name)
154
+ code << "modifiers << '#{name.downcase} ' if #{name.downcase}?\n"
155
+ end
156
+
157
+ class_eval <<-EOF
158
+ def modifier_string
159
+ modifiers = ''
160
+ #{code}
161
+ modifiers
162
+ end
163
+ EOF
164
+ end
165
+
166
+ class ClassMirror
167
+ include Annotated
168
+ include Modifiers
169
+
170
+ attr_reader :type, :interfaces
171
+ attr_accessor :superclass, :signature
172
+
173
+ def initialize(type, flags)
174
+ super()
175
+ @type = type
176
+ @flags = flags
177
+ @methods = Hash.new {|h, k| h[k] = {}}
178
+ @constructors = {}
179
+ @fields = {}
180
+ @interfaces = []
181
+ end
182
+
183
+ def self.load(name_or_bytes)
184
+ builder = BiteScript::ASM::ClassMirror::Builder.new
185
+ if name_or_bytes.kind_of?(String)
186
+ classname = name_or_bytes.tr('.', '/') + ".class"
187
+ stream = JRuby.runtime.jruby_class_loader.getResourceAsStream(
188
+ classname)
189
+ raise NameError, "Class '#{name_or_bytes}' not found." unless stream
190
+ name_or_bytes = stream
191
+ end
192
+ BiteScript::ASM::ClassReader.new(name_or_bytes).accept(builder, 3)
193
+ builder.mirror
194
+ end
195
+
196
+ def self.for_name(name)
197
+ load(name)
198
+ end
199
+
200
+ def getConstructor(*arg_types)
201
+ @constructors[arg_types]
202
+ end
203
+
204
+ def getConstructors
205
+ @constructors.values
206
+ end
207
+
208
+ def addConstructor(constructor)
209
+ @constructors[constructor.parameters] = constructor
210
+ end
211
+
212
+ def getDeclaredMethod(name, *args)
213
+ if args[0].kind_of?(Array)
214
+ args = args[0]
215
+ end
216
+ @methods[name][args]
217
+ end
218
+
219
+ def getDeclaredMethods(name=nil)
220
+ if name
221
+ @methods[name].values
222
+ else
223
+ @methods.values.map {|m| m.values}.flatten
224
+ end
225
+ end
226
+
227
+ def addMethod(method)
228
+ # TODO this is a hack to fix resolution of covariant returns.
229
+ # We should properly support methods that only differ by return type.
230
+ return if method.synthetic?
231
+ type_names = method.argument_types.map {|type| type.descriptor}
232
+ if method.name == '<init>'
233
+ @constructors[type_names] = method
234
+ else
235
+ @methods[method.name][type_names] = method
236
+ end
237
+ end
238
+
239
+ def getField(name)
240
+ @fields[name]
241
+ end
242
+
243
+ def getDeclaredFields
244
+ @fields.values
245
+ end
246
+
247
+ def addField(field)
248
+ @fields[field.name] = field
249
+ end
250
+
251
+ def type_parameters
252
+ signature.type_parameters is signature
253
+ end
254
+
255
+ def generic_superclass
256
+ signature.superclass if signature
257
+ end
258
+
259
+ def generic_interfaces
260
+ signature.interfaces if signature
261
+ end
262
+
263
+ def inspect
264
+ if annotation?
265
+ kind = "@interface"
266
+ elsif interface?
267
+ kind = "interface"
268
+ elsif enum?
269
+ kind = "enum"
270
+ else
271
+ kind = "class"
272
+ end
273
+ if superclass && !enum? && !interface?
274
+ extends = "extends #{superclass.getClassName} "
275
+ end
276
+ if self.interfaces && !self.interfaces.empty?
277
+ interfaces = self.interfaces.map{|i| i.class_name}.join(', ')
278
+ if interface?
279
+ extends = "extends #{interfaces} "
280
+ else
281
+ implements = "implements #{interfaces} "
282
+ end
283
+ end
284
+ result = "#{inspect_annotations}#{modifier_string}#{kind} "
285
+ result << "#{type.class_name} #{extends}{\n"
286
+ (getDeclaredFields + getConstructors + getDeclaredMethods).each do |f|
287
+ result << f.inspect << "\n"
288
+ end
289
+ result << "}"
290
+ end
291
+
292
+ class Builder
293
+ include BiteScript::ASM::ClassVisitor
294
+ include BiteScript::ASM::FieldVisitor
295
+ include BiteScript::ASM::MethodVisitor
296
+
297
+ def visit(version, access, name, signature, super_name, interfaces)
298
+ @current = @class = ClassMirror.new(Type.getObjectType(name), access)
299
+ @class.superclass = Type.getObjectType(super_name) if super_name
300
+ @class.signature = SignatureMirror.new(signature) if signature
301
+ if interfaces
302
+ interfaces.each do |i|
303
+ @class.interfaces << Type.getObjectType(i)
304
+ end
305
+ end
306
+ end
307
+
308
+ def mirror
309
+ @class
310
+ end
311
+
312
+ def visitSource(source, debug); end
313
+ def visitOuterClass(owner, name, desc); end
314
+ def visitAttribute(attribute); end
315
+ def visitInnerClass(name, outer, inner, access); end
316
+ def visitEnd; end
317
+
318
+ def visitAnnotation(desc, visible)
319
+ builder = AnnotationMirror::Builder.new(desc, visible)
320
+ @current.addAnnotation(builder.annotation)
321
+ builder
322
+ end
323
+
324
+ def visitField(flags, name, desc, signature, value)
325
+ signature = GenericTypeBuilder.read(signature)
326
+ @current = FieldMirror.new(@class.type, flags, name, Type.getType(desc), signature, value)
327
+ @class.addField(@current)
328
+ self
329
+ end
330
+
331
+ def visitMethod(flags, name, desc, signature, exceptions)
332
+ return_type = Type.getReturnType(desc)
333
+ parameters = Type.getArgumentTypes(desc).to_a
334
+ exceptions = (exceptions || []).map {|e| Type.getObjectType(e)}
335
+ signature = SignatureMirror.new(signature) if signature
336
+ @current = MethodMirror.new(
337
+ @class.type, flags, return_type, name, parameters, exceptions, signature)
338
+ @class.addMethod(@current)
339
+ # TODO parameter annotations, default value, etc.
340
+ self # This isn't legal is it?
341
+ end
342
+
343
+ def visitAnnotationDefault(*args);end
344
+
345
+ def to_s
346
+ "ClassMirror(#{type.class_name})"
347
+ end
348
+ end
349
+ end
350
+
351
+ class FieldMirror
352
+ include Modifiers
353
+ include Annotated
354
+
355
+ attr_reader :declaring_class, :name, :type, :value, :signature
356
+ def initialize(klass, flags, name, type, signature, value)
357
+ @declaring_class = klass
358
+ @flags = flags
359
+ @name = name
360
+ @type = type
361
+ @value = value
362
+ @signature = signature
363
+ end
364
+
365
+ def generic_type
366
+ signature
367
+ end
368
+
369
+ def inspect
370
+ inspect_annotations + "#{modifier_string}#{type.getClassName} #{name};"
371
+ end
372
+ end
373
+
374
+ class MethodMirror
375
+ include Modifiers
376
+ include Annotated
377
+
378
+ attr_reader :declaring_class, :name, :return_type
379
+ attr_reader :argument_types, :exception_types, :signature
380
+
381
+ def initialize(klass, flags, return_type, name, parameters, exceptions, signature)
382
+ @flags = flags
383
+ @declaring_class = klass
384
+ @name = name
385
+ @return_type = return_type
386
+ @argument_types = parameters
387
+ @exception_types = exceptions
388
+ end
389
+
390
+ def generic_parameter_types
391
+ signature.parameter_types if signature
392
+ end
393
+
394
+ def generic_return_type
395
+ signature.return_type if signature
396
+ end
397
+
398
+ def generic_exception_types
399
+ signature.exception_types if signature
400
+ end
401
+
402
+ def type_parameters
403
+ signature.type_parameters is signature
404
+ end
405
+
406
+ def inspect
407
+ "%s%s%s %s(%s);" % [
408
+ inspect_annotations,
409
+ modifier_string,
410
+ return_type.class_name,
411
+ name,
412
+ argument_types.map {|x| x.class_name}.join(', '),
413
+ ]
414
+ end
415
+ end
416
+
417
+ class SignatureMirror
418
+ include BiteScript::ASM::SignatureVisitor
419
+
420
+ attr_reader :type_parameters
421
+ attr_reader :parameter_types, :return_type, :exception_types
422
+ attr_reader :superclass, :interfaces
423
+
424
+ def method?
425
+ return_type != nil
426
+ end
427
+
428
+ def class?
429
+ superclass != nil
430
+ end
431
+
432
+ def initialize(signature=nil)
433
+ @type_parameters = []
434
+ @parameter_types = []
435
+ @exception_types = []
436
+ @interfaces = []
437
+ if (signature)
438
+ reader = BiteScript::ASM::SignatureReader.new(signature)
439
+ reader.accept(self)
440
+ end
441
+ end
442
+
443
+ def visitFormalTypeParameter(name)
444
+ type_parameters << TypeVariable.new(name)
445
+ end
446
+
447
+ def visitClassBound
448
+ GenericTypeBuilder.new {|bound| type_parameters[-1].bounds << bound}
449
+ end
450
+
451
+ def visitInterfaceBound
452
+ GenericTypeBuilder.new {|bound| type_parameters[-1].bounds << bound}
453
+ end
454
+
455
+ def visitParameterType
456
+ GenericTypeBuilder.new {|type| parameter_types << type}
457
+ end
458
+
459
+ def visitReturnType
460
+ GenericTypeBuilder.new {|type| @return_type = type}
461
+ end
462
+
463
+ def visitExceptionType
464
+ GenericTypeBuilder.new {|type| exception_types << type}
465
+ end
466
+
467
+ def visitSuperclass
468
+ GenericTypeBuilder.new {|type| @superclass = type}
469
+ end
470
+
471
+ def visitInterface
472
+ GenericTypeBuilder.new {|type| interfaces << type}
473
+ end
474
+ end
475
+
476
+ class GenericTypeMirror
477
+ def array?
478
+ false
479
+ end
480
+ def wildcard?
481
+ false
482
+ end
483
+ def generic_class?
484
+ false
485
+ end
486
+ def type_variable?
487
+ false
488
+ end
489
+ def inspect
490
+ "<#{self.class.name} #{to_s}>"
491
+ end
492
+ end
493
+
494
+ class TypeVariable < GenericTypeMirror
495
+ attr_reader :name, :bounds
496
+ def initialize(name)
497
+ @name = name
498
+ @bounds = []
499
+ end
500
+ def type_variable?
501
+ true
502
+ end
503
+
504
+ def to_s
505
+ result = "#{name}"
506
+ unless bounds.empty?
507
+ result << ' extends ' << bounds.map {|b| b.to_s}.join(' & ')
508
+ end
509
+ result
510
+ end
511
+ end
512
+
513
+ class GenericArray < GenericTypeMirror
514
+ attr_accessor :component_type
515
+ def array?
516
+ true
517
+ end
518
+ def to_s
519
+ "#{component_type}[]"
520
+ end
521
+ end
522
+
523
+ class Wildcard < GenericTypeMirror
524
+ attr_reader :lower_bound, :upper_bound
525
+ def initialize(upper_bound, lower_bound=nil)
526
+ @upper_bound = upper_bound
527
+ @lower_bound = lower_bound
528
+ end
529
+ def wildcard?
530
+ true
531
+ end
532
+ def to_s?
533
+ if lower_bound
534
+ "? super #{lower_bound}"
535
+ elsif upper_bound
536
+ "? extends #{upper_bound}"
537
+ else
538
+ "?"
539
+ end
540
+ end
541
+ end
542
+
543
+ class ParameterizedType < GenericTypeMirror
544
+ attr_reader :raw_type, :type_arguments, :outer_type
545
+
546
+ def initialize(raw_type, outer_type=nil)
547
+ @raw_type = raw_type
548
+ @type_arguments = []
549
+ @outer_type = outer_type
550
+ end
551
+
552
+ def descriptor
553
+ raw_type.descriptor
554
+ end
555
+
556
+ def generic_class?
557
+ true
558
+ end
559
+
560
+ def to_s
561
+ name = raw_type.internal_name.tr('/', '.')
562
+ unless type_arguments.empty?
563
+ name << "<#{type_arguments.map {|a| a.to_s}.join(', ')}>"
564
+ end
565
+ if outer_type
566
+ "#{outer_type}.#{name}"
567
+ else
568
+ name
569
+ end
570
+ end
571
+ end
572
+
573
+ class GenericTypeBuilder
574
+ include BiteScript::ASM::SignatureVisitor
575
+ attr_reader :result
576
+
577
+ def self.read(signature)
578
+ if signature
579
+ builder = GenericTypeBuilder.new
580
+ reader = BiteScript::ASM::SignatureReader.new(signature)
581
+ reader.accept(builder)
582
+ builder.result
583
+ end
584
+ end
585
+
586
+ def initialize(&block)
587
+ @block = block
588
+ end
589
+
590
+ def return_type(type)
591
+ @result = type
592
+ @block.call(type) if @block
593
+ end
594
+
595
+ def visitBaseType(desc)
596
+ return_type(Type.getType(desc.chr))
597
+ end
598
+
599
+ def visitArrayType
600
+ type = GenericArray.new
601
+ return_type(type)
602
+ GenericTypeBuilder.new {|component_type| type.component_type = component_type}
603
+ end
604
+
605
+ def visitTypeVariable(name)
606
+ return_type(TypeVariable.new(name))
607
+ end
608
+
609
+ def visitClassType(desc)
610
+ return_type(ParameterizedType.new(Type.getObjectType(desc)))
611
+ end
612
+
613
+ def visitTypeArgument(wildcard=nil)
614
+ if wildcard.nil?
615
+ @result.type_arguments <<
616
+ Wildcard.new(Type.getObjectType('java/lang/Object'))
617
+ return
618
+ end
619
+ GenericTypeBuilder.new do |type|
620
+ argument = case wildcard
621
+ when INSTANCEOF
622
+ type
623
+ when EXTENDS
624
+ Wildcard.new(type)
625
+ when SUPER
626
+ Wildcard.new(nil, type)
627
+ else
628
+ raise "Unknown wildcard #{wildcard.chr}"
629
+ end
630
+ @result.type_arguments << argument
631
+ end
632
+ end
633
+
634
+ def visitSuperclass
635
+ self
636
+ end
637
+
638
+ def visitInnerClassType(name)
639
+ desc = @result.descriptor.sub(/;$/, "$#{name};")
640
+ return_type(ParameterizedType.new(Type.getType(desc), @result))
641
+ end
642
+
643
+ def visitEnd
644
+ if @result.type_arguments.empty? && @result.outer_type.nil?
645
+ @result = @result.raw_type
646
+ end
647
+ end
648
+ end
649
+ end