bitescript 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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