mirah 0.0.4-java
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.
- data/History.txt +15 -0
- data/README.txt +51 -0
- data/Rakefile +86 -0
- data/bin/duby +10 -0
- data/bin/dubyc +10 -0
- data/bin/dubyp +10 -0
- data/bin/jrubyp +36 -0
- data/bin/mirah +9 -0
- data/bin/mirah.cmd +1 -0
- data/bin/mirahc +9 -0
- data/bin/mirahc.cmd +1 -0
- data/bin/mirahp +9 -0
- data/bin/mirahp.cmd +1 -0
- data/examples/ant/example-build.xml +7 -0
- data/examples/appengine/Rakefile +19 -0
- data/examples/appengine/Readme +29 -0
- data/examples/appengine/src/org/mirah/MirahApp.mirah +57 -0
- data/examples/appengine/src/org/mirah/list.dhtml +15 -0
- data/examples/appengine/war/WEB-INF/lib/dubydatastore.jar +0 -0
- data/examples/bintrees.mirah +66 -0
- data/examples/construction.mirah +8 -0
- data/examples/dynamic.mirah +17 -0
- data/examples/edb.mirah +3 -0
- data/examples/fib.mirah +16 -0
- data/examples/fields.mirah +22 -0
- data/examples/fractal.mirah +55 -0
- data/examples/java_thing.mirah +13 -0
- data/examples/plugins/appengine/Rakefile +55 -0
- data/examples/plugins/appengine/lib/com/google/appengine/ext/duby/db/datastore.rb +375 -0
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +336 -0
- data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +113 -0
- data/examples/simple_class.mirah +12 -0
- data/examples/sort_closure.mirah +7 -0
- data/examples/swing.mirah +20 -0
- data/examples/tak.mirah +15 -0
- data/examples/test.edb +9 -0
- data/examples/wiki/Rakefile +18 -0
- data/examples/wiki/src/org/mirah/wiki/MirahWiki.duby +324 -0
- data/examples/wiki/src/org/mirah/wiki/edit.eduby.html +42 -0
- data/examples/wiki/src/org/mirah/wiki/error.eduby.html +2 -0
- data/examples/wiki/src/org/mirah/wiki/layout.eduby.html +69 -0
- data/examples/wiki/src/org/mirah/wiki/parser.eduby.html +7 -0
- data/examples/wiki/src/org/mirah/wiki/view.eduby.html +15 -0
- data/examples/wiki/war/WEB-INF/classes/test/HeredocContext.class +0 -0
- data/examples/wiki/war/WEB-INF/classes/test/MirahParser.class +0 -0
- data/examples/wiki/war/WEB-INF/lib/appengine-api.jar +0 -0
- data/examples/wiki/war/WEB-INF/lib/dubydatastore.jar +0 -0
- data/examples/wiki/war/WEB-INF/lib/jmeta-runtime.jar +0 -0
- data/examples/wiki/war/WEB-INF/lib/pegdown-stubs.jar +0 -0
- data/examples/wiki/war/WEB-INF/pegdown.jar +0 -0
- data/examples/wiki/war/app.yaml +21 -0
- data/examples/wiki/war/public/favicon.ico +0 -0
- data/examples/wiki/war/public/images/appengine_duby.png +0 -0
- data/examples/wiki/war/public/images/back.gif +0 -0
- data/examples/wiki/war/public/images/dir.gif +0 -0
- data/examples/wiki/war/public/images/file.gif +0 -0
- data/examples/wiki/war/public/javascripts/prettify.js +61 -0
- data/examples/wiki/war/public/robots.txt +0 -0
- data/examples/wiki/war/public/stylesheets/main.css +156 -0
- data/examples/wiki/war/public/stylesheets/prettify.css +1 -0
- data/examples/wiki/war/public/stylesheets/sh_style.css +66 -0
- data/examples/wiki/war/public/stylesheets/source.css +21 -0
- data/examples/wiki/war/public/wmd/images/bg-fill.png +0 -0
- data/examples/wiki/war/public/wmd/images/bg.png +0 -0
- data/examples/wiki/war/public/wmd/images/blockquote.png +0 -0
- data/examples/wiki/war/public/wmd/images/bold.png +0 -0
- data/examples/wiki/war/public/wmd/images/code.png +0 -0
- data/examples/wiki/war/public/wmd/images/h1.png +0 -0
- data/examples/wiki/war/public/wmd/images/hr.png +0 -0
- data/examples/wiki/war/public/wmd/images/img.png +0 -0
- data/examples/wiki/war/public/wmd/images/italic.png +0 -0
- data/examples/wiki/war/public/wmd/images/link.png +0 -0
- data/examples/wiki/war/public/wmd/images/ol.png +0 -0
- data/examples/wiki/war/public/wmd/images/redo.png +0 -0
- data/examples/wiki/war/public/wmd/images/separator.png +0 -0
- data/examples/wiki/war/public/wmd/images/ul.png +0 -0
- data/examples/wiki/war/public/wmd/images/undo.png +0 -0
- data/examples/wiki/war/public/wmd/images/wmd-on.png +0 -0
- data/examples/wiki/war/public/wmd/images/wmd.png +0 -0
- data/examples/wiki/war/public/wmd/showdown.js +421 -0
- data/examples/wiki/war/public/wmd/wmd-base.js +1799 -0
- data/examples/wiki/war/public/wmd/wmd-plus.js +311 -0
- data/examples/wiki/war/public/wmd/wmd.js +73 -0
- data/javalib/JRubyParser.jar +0 -0
- data/javalib/dynalang-invoke-0.1.jar +0 -0
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/lib/duby.rb +2 -0
- data/lib/mirah.rb +338 -0
- data/lib/mirah/appengine_tasks.rb +146 -0
- data/lib/mirah/ast.rb +615 -0
- data/lib/mirah/ast/call.rb +307 -0
- data/lib/mirah/ast/class.rb +311 -0
- data/lib/mirah/ast/flow.rb +364 -0
- data/lib/mirah/ast/intrinsics.rb +470 -0
- data/lib/mirah/ast/literal.rb +154 -0
- data/lib/mirah/ast/local.rb +89 -0
- data/lib/mirah/ast/method.rb +360 -0
- data/lib/mirah/ast/scope.rb +208 -0
- data/lib/mirah/ast/structure.rb +226 -0
- data/lib/mirah/ast/type.rb +130 -0
- data/lib/mirah/compiler.rb +341 -0
- data/lib/mirah/env.rb +33 -0
- data/lib/mirah/jvm/base.rb +258 -0
- data/lib/mirah/jvm/compiler.rb +885 -0
- data/lib/mirah/jvm/method_lookup.rb +203 -0
- data/lib/mirah/jvm/source_compiler.rb +737 -0
- data/lib/mirah/jvm/source_generator/builder.rb +444 -0
- data/lib/mirah/jvm/source_generator/loops.rb +110 -0
- data/lib/mirah/jvm/source_generator/precompile.rb +188 -0
- data/lib/mirah/jvm/source_generator/typer.rb +11 -0
- data/lib/mirah/jvm/typer.rb +151 -0
- data/lib/mirah/jvm/types.rb +416 -0
- data/lib/mirah/jvm/types/basic_types.rb +33 -0
- data/lib/mirah/jvm/types/boolean.rb +17 -0
- data/lib/mirah/jvm/types/enumerable.rb +65 -0
- data/lib/mirah/jvm/types/extensions.rb +86 -0
- data/lib/mirah/jvm/types/factory.rb +186 -0
- data/lib/mirah/jvm/types/floats.rb +86 -0
- data/lib/mirah/jvm/types/integers.rb +171 -0
- data/lib/mirah/jvm/types/intrinsics.rb +376 -0
- data/lib/mirah/jvm/types/literals.rb +74 -0
- data/lib/mirah/jvm/types/methods.rb +614 -0
- data/lib/mirah/jvm/types/number.rb +143 -0
- data/lib/mirah/nbcompiler.rb +29 -0
- data/lib/mirah/plugin/edb.rb +29 -0
- data/lib/mirah/plugin/gwt.rb +173 -0
- data/lib/mirah/plugin/java.rb +55 -0
- data/lib/mirah/transform.rb +266 -0
- data/lib/mirah/transform2.rb +728 -0
- data/lib/mirah/typer.rb +407 -0
- data/lib/mirah_task.rb +107 -0
- data/test/test_ast.rb +359 -0
- data/test/test_compilation.rb +112 -0
- data/test/test_env.rb +42 -0
- data/test/test_gwt.rb +58 -0
- data/test/test_java_typer.rb +183 -0
- data/test/test_javac_compiler.rb +63 -0
- data/test/test_jvm_compiler.rb +2607 -0
- data/test/test_typer.rb +221 -0
- metadata +235 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require 'appengine-sdk'
|
|
2
|
+
require 'mirah_task'
|
|
3
|
+
require 'java'
|
|
4
|
+
require 'open-uri'
|
|
5
|
+
require 'rake'
|
|
6
|
+
require 'yaml'
|
|
7
|
+
|
|
8
|
+
module AppEngine::Rake
|
|
9
|
+
SERVLET = AppEngine::SDK::SDK_ROOT +
|
|
10
|
+
'/lib/shared/geronimo-servlet_2.5_spec-1.2.jar'
|
|
11
|
+
APIS = AppEngine::SDK::API_JAR
|
|
12
|
+
TOOLS = AppEngine::SDK::TOOLS_JAR
|
|
13
|
+
|
|
14
|
+
$CLASSPATH << SERVLET
|
|
15
|
+
$CLASSPATH << APIS
|
|
16
|
+
$CLASSPATH << TOOLS
|
|
17
|
+
|
|
18
|
+
class AppEngineTask < Rake::Task
|
|
19
|
+
def initialize(*args, &block)
|
|
20
|
+
super
|
|
21
|
+
AppEngineTask.tasks << self
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def init(src, war)
|
|
25
|
+
@src = src
|
|
26
|
+
@war = war
|
|
27
|
+
unless $CLASSPATH.include?(webinf_classes)
|
|
28
|
+
$CLASSPATH << webinf_classes
|
|
29
|
+
end
|
|
30
|
+
webinf_lib_jars.each do |jar|
|
|
31
|
+
$CLASSPATH << jar unless $CLASSPATH.include?(jar)
|
|
32
|
+
end
|
|
33
|
+
Duby.source_paths << src
|
|
34
|
+
Duby.dest_paths << webinf_classes
|
|
35
|
+
directory(webinf_classes)
|
|
36
|
+
directory(webinf_lib)
|
|
37
|
+
|
|
38
|
+
file_create api_jar => webinf_lib do
|
|
39
|
+
puts 'Coping apis'
|
|
40
|
+
cp APIS, api_jar
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
task :server => [name] do
|
|
44
|
+
check_for_updates
|
|
45
|
+
args = [
|
|
46
|
+
'java', '-cp', TOOLS,
|
|
47
|
+
'com.google.appengine.tools.KickStart',
|
|
48
|
+
'com.google.appengine.tools.development.DevAppServerMain',
|
|
49
|
+
@war
|
|
50
|
+
]
|
|
51
|
+
system *args
|
|
52
|
+
@done = true
|
|
53
|
+
@update_thread.join
|
|
54
|
+
end
|
|
55
|
+
task :upload => [name] do
|
|
56
|
+
Java::ComGoogleAppengineTools::AppCfg.main(
|
|
57
|
+
['update', @war].to_java(:string))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
enhance([api_jar])
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def real_prerequisites
|
|
64
|
+
prerequisites.map {|n| application[n, scope]}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def check_for_updates
|
|
68
|
+
@update_thread = Thread.new do
|
|
69
|
+
# Give the server time to start
|
|
70
|
+
next_time = Time.now + 5
|
|
71
|
+
until @done
|
|
72
|
+
sleep_time = next_time - Time.now
|
|
73
|
+
sleep(sleep_time) if sleep_time > 0
|
|
74
|
+
next_time = Time.now + 1
|
|
75
|
+
update
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def update
|
|
81
|
+
begin
|
|
82
|
+
timestamp = app_yaml_timestamp
|
|
83
|
+
@last_app_yaml_timestamp ||= timestamp
|
|
84
|
+
updated = false
|
|
85
|
+
real_prerequisites.each do |dep|
|
|
86
|
+
if dep.needed?
|
|
87
|
+
puts "Executing #{dep.name}"
|
|
88
|
+
dep.execute
|
|
89
|
+
updated = true
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
if updated || (timestamp != @last_app_yaml_timestamp)
|
|
93
|
+
begin
|
|
94
|
+
open('http://localhost:8080/_ah/reloadwebapp')
|
|
95
|
+
@last_app_yaml_timestamp = timestamp
|
|
96
|
+
rescue OpenURI::HTTPError
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
rescue Exception
|
|
100
|
+
puts $!, $@
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def app_yaml_timestamp
|
|
105
|
+
if File.exist?(app_yaml)
|
|
106
|
+
File.mtime(app_yaml)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def app_yaml
|
|
111
|
+
@war + '/app.yaml'
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def webinf_classes
|
|
115
|
+
@war + '/WEB-INF/classes'
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def webinf_lib
|
|
119
|
+
@war + '/WEB-INF/lib'
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def api_jar
|
|
123
|
+
File.join(webinf_lib, File.basename(APIS))
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def webinf_lib_jars
|
|
127
|
+
Dir.glob(webinf_lib + '/*.jar')
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def appengine_app(*args, &block)
|
|
133
|
+
deps = []
|
|
134
|
+
if args[-1].kind_of?(Hash)
|
|
135
|
+
hash = args.pop
|
|
136
|
+
arg = hash.keys[0]
|
|
137
|
+
deps = hash[arg]
|
|
138
|
+
args << arg
|
|
139
|
+
end
|
|
140
|
+
name, src, war = args
|
|
141
|
+
task = AppEngine::Rake::AppEngineTask.define_task(name => deps, &block)
|
|
142
|
+
src = File.expand_path(src || 'src')
|
|
143
|
+
war = File.expand_path(war || 'war')
|
|
144
|
+
task.init(src, war)
|
|
145
|
+
task
|
|
146
|
+
end
|
data/lib/mirah/ast.rb
ADDED
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
require 'mirah/transform'
|
|
2
|
+
require 'mirah/ast/scope'
|
|
3
|
+
|
|
4
|
+
module Duby
|
|
5
|
+
module AST
|
|
6
|
+
class << self
|
|
7
|
+
attr_accessor :verbose
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# The top of the AST class hierarchy, this represents an abstract AST node.
|
|
11
|
+
# It provides accessors for _children_, an array of all child nodes,
|
|
12
|
+
# _parent_, a reference to this node's parent (nil if none), and _newline_,
|
|
13
|
+
# whether this node represents a new line.
|
|
14
|
+
class Node
|
|
15
|
+
include Java::DubyLangCompiler.Node
|
|
16
|
+
include Enumerable
|
|
17
|
+
|
|
18
|
+
attr_accessor :children
|
|
19
|
+
attr_accessor :parent
|
|
20
|
+
attr_accessor :position
|
|
21
|
+
attr_accessor :newline
|
|
22
|
+
attr_accessor :inferred_type
|
|
23
|
+
|
|
24
|
+
def self.child(name)
|
|
25
|
+
@children ||= []
|
|
26
|
+
index = @children.size
|
|
27
|
+
class_eval <<-EOF
|
|
28
|
+
def #{name}
|
|
29
|
+
@children[#{index}]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def #{name}=(node)
|
|
33
|
+
@children[#{index}] = _set_parent(node)
|
|
34
|
+
end
|
|
35
|
+
EOF
|
|
36
|
+
@children << name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.child_name(i)
|
|
40
|
+
@children[i] if @children
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def child_nodes
|
|
44
|
+
java.util.ArrayList.new(@children)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def initialize(parent, position, children = [])
|
|
48
|
+
JRuby.reference(self.class).setRubyClassAllocator(JRuby.reference(self.class).reified_class)
|
|
49
|
+
unless parent.nil? || Duby::AST::Node === parent
|
|
50
|
+
raise "Duby::AST::Node.new parent #{parent.class} must be nil or === Duby::AST::Node."
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@parent = parent
|
|
54
|
+
@newline = false
|
|
55
|
+
@inferred_type = nil
|
|
56
|
+
@resolved = false
|
|
57
|
+
@position = position
|
|
58
|
+
if block_given?
|
|
59
|
+
@children ||= []
|
|
60
|
+
@children = yield(self) || []
|
|
61
|
+
else
|
|
62
|
+
@children = children
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def _dump(depth)
|
|
67
|
+
to_skip = %w(@parent @newline @inferred_type @resolved @proxy @scope @class_scope @typer)
|
|
68
|
+
vars = {}
|
|
69
|
+
instance_variables.each do |name|
|
|
70
|
+
next if to_skip.include?(name)
|
|
71
|
+
vars[name] = instance_variable_get(name)
|
|
72
|
+
begin
|
|
73
|
+
Marshal.dump(vars[name]) if AST.verbose
|
|
74
|
+
rescue
|
|
75
|
+
puts "#{self}: Failed to marshal #{name}"
|
|
76
|
+
puts $!, $@
|
|
77
|
+
raise $!
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
Marshal.dump(vars)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self._load(vars)
|
|
84
|
+
node = self.allocate
|
|
85
|
+
Marshal.load(vars).each do |name, value|
|
|
86
|
+
node.instance_variable_set(name, value)
|
|
87
|
+
end
|
|
88
|
+
node.children.each do |child|
|
|
89
|
+
node._set_parent(child)
|
|
90
|
+
end
|
|
91
|
+
node.validate_children
|
|
92
|
+
node
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def validate_children
|
|
96
|
+
validate_name if respond_to?(:validate_name)
|
|
97
|
+
children.each_with_index do |child, i|
|
|
98
|
+
validate_child(child, i)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def validate_child(child, i)
|
|
103
|
+
name = self.class.child_name(i)
|
|
104
|
+
validator = :"validate_#{name}"
|
|
105
|
+
if name && respond_to?(validator)
|
|
106
|
+
send validator
|
|
107
|
+
else
|
|
108
|
+
if UnquotedValue === child
|
|
109
|
+
self[i] = child.node
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def line_number
|
|
115
|
+
if @position
|
|
116
|
+
@position.start_line + 1
|
|
117
|
+
else
|
|
118
|
+
0
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def log(message)
|
|
123
|
+
puts "* [AST] [#{simple_name}] " + message if AST.verbose
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def inspect_children(indent = 0)
|
|
127
|
+
indent_str = ' ' * indent
|
|
128
|
+
str = ''
|
|
129
|
+
children.each_with_index do |child, i|
|
|
130
|
+
extra_indent = 0
|
|
131
|
+
if child
|
|
132
|
+
name = self.class.child_name(i)
|
|
133
|
+
if Duby::AST.verbose && name
|
|
134
|
+
str << "\n#{indent_str} #{name}:"
|
|
135
|
+
extra_indent = 1
|
|
136
|
+
end
|
|
137
|
+
if ::Array === child
|
|
138
|
+
child.each {|ary_child|
|
|
139
|
+
if Duby::AST.verbose && Node === ary_child && ary_child.parent != self
|
|
140
|
+
str << "\n#{indent_str} (wrong parent)"
|
|
141
|
+
end
|
|
142
|
+
str << "\n#{ary_child.inspect(indent + extra_indent + 1)}"
|
|
143
|
+
}
|
|
144
|
+
elsif ::Hash === child
|
|
145
|
+
str << "\n#{indent_str} #{child.inspect}"
|
|
146
|
+
else
|
|
147
|
+
if Duby::AST.verbose && Node === child && child.parent != self
|
|
148
|
+
str << "\n#{indent_str} (wrong parent)"
|
|
149
|
+
end
|
|
150
|
+
str << "\n#{child.inspect(indent + extra_indent + 1)}"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
str
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def inspect(indent = 0)
|
|
158
|
+
indent_str = ' ' * indent
|
|
159
|
+
indent_str << to_s << inspect_children(indent)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def simple_name
|
|
163
|
+
self.class.name.split("::")[-1]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def to_s; simple_name; end
|
|
167
|
+
|
|
168
|
+
def [](index) children[index] end
|
|
169
|
+
|
|
170
|
+
def []=(index, node)
|
|
171
|
+
node.parent = self
|
|
172
|
+
@children[index] = node
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def each(&b) children.each(&b) end
|
|
176
|
+
|
|
177
|
+
def <<(node)
|
|
178
|
+
@children << _set_parent(node)
|
|
179
|
+
self
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def insert(index, node)
|
|
183
|
+
node.parent = self
|
|
184
|
+
@children.insert(index, node)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def empty?
|
|
188
|
+
@children.empty?
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def resolved!(typer=nil)
|
|
192
|
+
log "#{to_s} resolved!"
|
|
193
|
+
@resolved = true
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def resolved?; @resolved end
|
|
197
|
+
|
|
198
|
+
def resolve_if(typer)
|
|
199
|
+
unless resolved?
|
|
200
|
+
@inferred_type = yield
|
|
201
|
+
@inferred_type ? resolved!(typer) : typer.defer(self)
|
|
202
|
+
end
|
|
203
|
+
@inferred_type
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def self.===(other)
|
|
207
|
+
super || (other.kind_of?(NodeProxy) && (self === other.__getobj__))
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def _set_parent(node)
|
|
211
|
+
case node
|
|
212
|
+
when Node
|
|
213
|
+
node.parent = self
|
|
214
|
+
when ::Array
|
|
215
|
+
node.each {|x| x.parent = self if x}
|
|
216
|
+
end
|
|
217
|
+
node
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def initialize_copy(other)
|
|
221
|
+
@parent = nil
|
|
222
|
+
@children = []
|
|
223
|
+
other.children.each do |child|
|
|
224
|
+
case child
|
|
225
|
+
when ::Array
|
|
226
|
+
self << child.map {|x| x.dup}
|
|
227
|
+
when nil
|
|
228
|
+
self << nil
|
|
229
|
+
else
|
|
230
|
+
self << child.dup
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def inferred_type!
|
|
236
|
+
unless @inferred_type
|
|
237
|
+
raise Duby::Typer::InferenceError.new(
|
|
238
|
+
"Internal Error: #{self.class} never inferred", self)
|
|
239
|
+
end
|
|
240
|
+
inferred_type
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class ErrorNode < Node
|
|
246
|
+
def initialize(parent, error)
|
|
247
|
+
super(parent, error.position)
|
|
248
|
+
@error = error
|
|
249
|
+
@inferred_type = TypeReference::ErrorType
|
|
250
|
+
@resolved = true
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def infer(typer)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
module Named
|
|
258
|
+
attr_accessor :name
|
|
259
|
+
|
|
260
|
+
def to_s
|
|
261
|
+
"#{super}(#{name})"
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def validate_name
|
|
265
|
+
if UnquotedValue === @name
|
|
266
|
+
@name = @name.name
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
module Typed
|
|
272
|
+
attr_accessor :type
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
module Valued
|
|
276
|
+
include Typed
|
|
277
|
+
attr_accessor :value
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
module Literal
|
|
281
|
+
include Typed
|
|
282
|
+
attr_accessor :literal
|
|
283
|
+
|
|
284
|
+
def to_s
|
|
285
|
+
"#{super}(#{literal.inspect})"
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
module Annotated
|
|
290
|
+
attr_accessor :annotations
|
|
291
|
+
|
|
292
|
+
def annotation(name)
|
|
293
|
+
name = name.to_s
|
|
294
|
+
annotations.find {|a| a.name == name}
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
module Binding
|
|
299
|
+
def binding_type(duby=nil)
|
|
300
|
+
static_scope.binding_type(defining_class, duby)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def binding_type=(type)
|
|
304
|
+
static_scope.binding_type = type
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def has_binding?
|
|
308
|
+
static_scope.has_binding?
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
class Colon2 < Node; end
|
|
313
|
+
|
|
314
|
+
class Constant < Node
|
|
315
|
+
include Named
|
|
316
|
+
include Scoped
|
|
317
|
+
attr_accessor :array
|
|
318
|
+
|
|
319
|
+
def initialize(parent, position, name)
|
|
320
|
+
@name = name
|
|
321
|
+
super(parent, position, [])
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def infer(typer)
|
|
325
|
+
@inferred_type ||= begin
|
|
326
|
+
# TODO lookup constant, inline if we're supposed to.
|
|
327
|
+
begin
|
|
328
|
+
typer.type_reference(scope, name, @array, true)
|
|
329
|
+
rescue NameError => ex
|
|
330
|
+
typer.known_types[@name] = Duby::AST.error_type
|
|
331
|
+
raise ex
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def type_reference(typer)
|
|
337
|
+
begin
|
|
338
|
+
typer.type_reference(scope, @name, @array)
|
|
339
|
+
rescue NameError => ex
|
|
340
|
+
typer.known_types[@name] = Duby::AST.error_type
|
|
341
|
+
raise ex
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
class Self < Node
|
|
347
|
+
include Scoped
|
|
348
|
+
def infer(typer)
|
|
349
|
+
@inferred_type ||= scope.static_scope.self_type
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
class Annotation < Node
|
|
354
|
+
attr_reader :values
|
|
355
|
+
attr_accessor :runtime
|
|
356
|
+
alias runtime? runtime
|
|
357
|
+
|
|
358
|
+
child :name_node
|
|
359
|
+
|
|
360
|
+
def initialize(parent, position, name=nil, &block)
|
|
361
|
+
super(parent, position, &block)
|
|
362
|
+
if name
|
|
363
|
+
@name = if name.respond_to?(:class_name)
|
|
364
|
+
name.class_name
|
|
365
|
+
else
|
|
366
|
+
name.name
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
@values = {}
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def name
|
|
373
|
+
@name
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def type
|
|
377
|
+
BiteScript::ASM::Type.getObjectType(@name.tr('.', '/'))
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def []=(name, value)
|
|
381
|
+
@values[name] = value
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def [](name)
|
|
385
|
+
@values[name]
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def infer(typer)
|
|
389
|
+
@inferred ||= begin
|
|
390
|
+
@name = name_node.type_reference(typer).name if name_node
|
|
391
|
+
@values.each do |name, value|
|
|
392
|
+
if Node === value
|
|
393
|
+
@values[name] = annotation_value(value, typer)
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
true
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def annotation_value(node, typer)
|
|
401
|
+
case node
|
|
402
|
+
when String
|
|
403
|
+
java.lang.String.new(node.literal)
|
|
404
|
+
when Array
|
|
405
|
+
node.children.map {|node| annotation_value(node, typer)}
|
|
406
|
+
else
|
|
407
|
+
# TODO Support other types
|
|
408
|
+
ref = value.type_refence(typer)
|
|
409
|
+
desc = BiteScript::Signature.class_id(ref)
|
|
410
|
+
BiteScript::ASM::Type.getType(desc)
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
class TypeReference < Node
|
|
416
|
+
include Named
|
|
417
|
+
attr_accessor :array
|
|
418
|
+
alias array? array
|
|
419
|
+
attr_accessor :meta
|
|
420
|
+
alias meta? meta
|
|
421
|
+
|
|
422
|
+
def initialize(name, array = false, meta = false, position=nil)
|
|
423
|
+
super(nil, position)
|
|
424
|
+
@name = name
|
|
425
|
+
@array = array
|
|
426
|
+
@meta = meta
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def type_reference(typer)
|
|
430
|
+
typer.type_reference(nil, name, array, meta)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
def to_s
|
|
434
|
+
"Type(#{name}#{array? ? ' array' : ''}#{meta? ? ' meta' : ''})"
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def full_name
|
|
438
|
+
"#{name}#{array ? '[]' : ''}"
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def ==(other)
|
|
442
|
+
to_s == other.to_s
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def eql?(other)
|
|
446
|
+
self == other
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
def hash
|
|
450
|
+
to_s.hash
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def is_parent(other)
|
|
454
|
+
# default behavior now is to disallow any polymorphic types
|
|
455
|
+
self == other
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
def compatible?(other)
|
|
459
|
+
# default behavior is only exact match right now
|
|
460
|
+
self == other ||
|
|
461
|
+
error? || other.error? ||
|
|
462
|
+
unreachable? || other.unreachable?
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def iterable?
|
|
466
|
+
array?
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
def component_type
|
|
470
|
+
AST.type(nil, name) if array?
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def basic_type
|
|
474
|
+
if array? || meta?
|
|
475
|
+
TypeReference.new(name, false, false)
|
|
476
|
+
else
|
|
477
|
+
self
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
def narrow(other)
|
|
482
|
+
# only exact match allowed for now, so narrowing is a noop
|
|
483
|
+
if error? || unreachable?
|
|
484
|
+
other
|
|
485
|
+
else
|
|
486
|
+
self
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def unmeta
|
|
491
|
+
TypeReference.new(name, array, false)
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
def meta
|
|
495
|
+
TypeReference.new(name, array, true)
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def void?
|
|
499
|
+
name == :void
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
def error?
|
|
503
|
+
name == :error
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
def null?
|
|
507
|
+
name == :null
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
def unreachable?
|
|
511
|
+
name == :unreachable
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
def block?
|
|
515
|
+
name == :block
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
def primitive?
|
|
519
|
+
true
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
def _dump(depth)
|
|
523
|
+
Marshal.dump([name, array?, meta?])
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
def self._load(str)
|
|
527
|
+
AST::Type(*Marshal.load(str))
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
NoType = TypeReference.new(:notype)
|
|
531
|
+
NullType = TypeReference.new(:null)
|
|
532
|
+
ErrorType = TypeReference.new(:error)
|
|
533
|
+
UnreachableType = TypeReference.new(:unreachable)
|
|
534
|
+
BlockType = TypeReference.new(:block)
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
class TypeDefinition < TypeReference
|
|
538
|
+
attr_accessor :superclass, :interfaces
|
|
539
|
+
|
|
540
|
+
def initialize(name, superclass, interfaces)
|
|
541
|
+
super(name, false)
|
|
542
|
+
|
|
543
|
+
@superclass = superclass
|
|
544
|
+
@interfaces = interfaces
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
def self.type_factory
|
|
549
|
+
Thread.current[:ast_type_factory]
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
def self.type_factory=(factory)
|
|
553
|
+
Thread.current[:ast_type_factory] = factory
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# Shortcut method to construct type references
|
|
557
|
+
def self.type(scope, typesym, array = false, meta = false)
|
|
558
|
+
factory = type_factory
|
|
559
|
+
if factory
|
|
560
|
+
factory.type(scope, typesym, array, meta)
|
|
561
|
+
else
|
|
562
|
+
TypeReference.new(typesym, array, meta)
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
def self.no_type
|
|
567
|
+
factory = type_factory
|
|
568
|
+
if factory
|
|
569
|
+
factory.no_type
|
|
570
|
+
else
|
|
571
|
+
TypeReference::NoType
|
|
572
|
+
end
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def self.error_type
|
|
576
|
+
TypeReference::ErrorType
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
def self.unreachable_type
|
|
580
|
+
TypeReference::UnreachableType
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
def self.block_type
|
|
584
|
+
TypeReference::BlockType
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
def self.fixnum(parent, position, literal)
|
|
588
|
+
Fixnum.new(parent, position, literal)
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
def self.float(parent, position, literal)
|
|
592
|
+
Float.new(parent, position, literal)
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
def self.defmacro(name, &block)
|
|
596
|
+
@macros ||= {}
|
|
597
|
+
raise "Conflicting macros for #{name}" if @macros[name]
|
|
598
|
+
@macros[name] = block
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
def self.macro(name)
|
|
602
|
+
@macros[name]
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
require 'mirah/ast/local'
|
|
608
|
+
require 'mirah/ast/call'
|
|
609
|
+
require 'mirah/ast/flow'
|
|
610
|
+
require 'mirah/ast/literal'
|
|
611
|
+
require 'mirah/ast/method'
|
|
612
|
+
require 'mirah/ast/class'
|
|
613
|
+
require 'mirah/ast/structure'
|
|
614
|
+
require 'mirah/ast/type'
|
|
615
|
+
require 'mirah/ast/intrinsics'
|