rsense-core 0.5.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.
Files changed (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +1 -0
  5. data/README.md +35 -0
  6. data/Rakefile +84 -0
  7. data/TypeAnnotation.tokens +41 -0
  8. data/build.xml +84 -0
  9. data/build_lib/antlr-3.2.jar +0 -0
  10. data/lib/jars/ant-1.7.0.jar +0 -0
  11. data/lib/jars/ant-launcher-1.7.0.jar +0 -0
  12. data/lib/jars/antlr-runtime-3.2.jar +0 -0
  13. data/lib/jars/bsf-2.3.0.jar +0 -0
  14. data/lib/rsense-core.rb +28 -0
  15. data/lib/rsense.jar +0 -0
  16. data/lib/rsense/core.rb +5 -0
  17. data/lib/rsense/core/version.rb +5 -0
  18. data/lib/rsense/parser.rb +6 -0
  19. data/lib/rsense/ruby.rb +19 -0
  20. data/lib/rsense/typing.rb +13 -0
  21. data/lib/rsense/typing/annotation.rb +20 -0
  22. data/lib/rsense/typing/runtime.rb +23 -0
  23. data/lib/rsense/typing/vertex.rb +15 -0
  24. data/lib/rsense/util.rb +9 -0
  25. data/rsense-core.gemspec +30 -0
  26. data/src/org/cx4a/rsense/CodeAssist.java +744 -0
  27. data/src/org/cx4a/rsense/CodeAssistError.java +31 -0
  28. data/src/org/cx4a/rsense/CodeAssistResult.java +42 -0
  29. data/src/org/cx4a/rsense/CodeCompletionResult.java +65 -0
  30. data/src/org/cx4a/rsense/FindDefinitionResult.java +24 -0
  31. data/src/org/cx4a/rsense/LoadResult.java +19 -0
  32. data/src/org/cx4a/rsense/Main.java +916 -0
  33. data/src/org/cx4a/rsense/Options.java +353 -0
  34. data/src/org/cx4a/rsense/Project.java +103 -0
  35. data/src/org/cx4a/rsense/TypeInferenceResult.java +25 -0
  36. data/src/org/cx4a/rsense/WhereResult.java +19 -0
  37. data/src/org/cx4a/rsense/parser/TypeAnnotation.g +221 -0
  38. data/src/org/cx4a/rsense/parser/TypeAnnotationLexer.java +1759 -0
  39. data/src/org/cx4a/rsense/parser/TypeAnnotationParser.java +2025 -0
  40. data/src/org/cx4a/rsense/ruby/Block.java +10 -0
  41. data/src/org/cx4a/rsense/ruby/Context.java +75 -0
  42. data/src/org/cx4a/rsense/ruby/DynamicMethod.java +10 -0
  43. data/src/org/cx4a/rsense/ruby/DynamicScope.java +51 -0
  44. data/src/org/cx4a/rsense/ruby/Frame.java +95 -0
  45. data/src/org/cx4a/rsense/ruby/IRubyObject.java +17 -0
  46. data/src/org/cx4a/rsense/ruby/LocalScope.java +43 -0
  47. data/src/org/cx4a/rsense/ruby/MetaClass.java +50 -0
  48. data/src/org/cx4a/rsense/ruby/Ruby.java +242 -0
  49. data/src/org/cx4a/rsense/ruby/RubyClass.java +146 -0
  50. data/src/org/cx4a/rsense/ruby/RubyModule.java +255 -0
  51. data/src/org/cx4a/rsense/ruby/RubyObject.java +94 -0
  52. data/src/org/cx4a/rsense/ruby/Scope.java +7 -0
  53. data/src/org/cx4a/rsense/ruby/SpecialObject.java +15 -0
  54. data/src/org/cx4a/rsense/ruby/Visibility.java +17 -0
  55. data/src/org/cx4a/rsense/typing/Graph.java +1690 -0
  56. data/src/org/cx4a/rsense/typing/Propagation.java +73 -0
  57. data/src/org/cx4a/rsense/typing/Template.java +84 -0
  58. data/src/org/cx4a/rsense/typing/TemplateAttribute.java +158 -0
  59. data/src/org/cx4a/rsense/typing/TypeSet.java +48 -0
  60. data/src/org/cx4a/rsense/typing/annotation/ClassType.java +57 -0
  61. data/src/org/cx4a/rsense/typing/annotation/MethodType.java +79 -0
  62. data/src/org/cx4a/rsense/typing/annotation/TypeAnnotation.java +4 -0
  63. data/src/org/cx4a/rsense/typing/annotation/TypeAny.java +7 -0
  64. data/src/org/cx4a/rsense/typing/annotation/TypeApplication.java +37 -0
  65. data/src/org/cx4a/rsense/typing/annotation/TypeConstraint.java +29 -0
  66. data/src/org/cx4a/rsense/typing/annotation/TypeExpression.java +11 -0
  67. data/src/org/cx4a/rsense/typing/annotation/TypeIdentity.java +59 -0
  68. data/src/org/cx4a/rsense/typing/annotation/TypeOptional.java +22 -0
  69. data/src/org/cx4a/rsense/typing/annotation/TypePragma.java +22 -0
  70. data/src/org/cx4a/rsense/typing/annotation/TypeSplat.java +22 -0
  71. data/src/org/cx4a/rsense/typing/annotation/TypeTuple.java +35 -0
  72. data/src/org/cx4a/rsense/typing/annotation/TypeUnion.java +23 -0
  73. data/src/org/cx4a/rsense/typing/annotation/TypeVariable.java +44 -0
  74. data/src/org/cx4a/rsense/typing/runtime/AliasMethod.java +94 -0
  75. data/src/org/cx4a/rsense/typing/runtime/AnnotationHelper.java +69 -0
  76. data/src/org/cx4a/rsense/typing/runtime/AnnotationResolver.java +523 -0
  77. data/src/org/cx4a/rsense/typing/runtime/Array.java +84 -0
  78. data/src/org/cx4a/rsense/typing/runtime/ClassTag.java +27 -0
  79. data/src/org/cx4a/rsense/typing/runtime/DefaultMethod.java +115 -0
  80. data/src/org/cx4a/rsense/typing/runtime/Hash.java +131 -0
  81. data/src/org/cx4a/rsense/typing/runtime/LoopTag.java +21 -0
  82. data/src/org/cx4a/rsense/typing/runtime/Method.java +32 -0
  83. data/src/org/cx4a/rsense/typing/runtime/MonomorphicObject.java +77 -0
  84. data/src/org/cx4a/rsense/typing/runtime/ObjectAllocator.java +40 -0
  85. data/src/org/cx4a/rsense/typing/runtime/PolymorphicObject.java +90 -0
  86. data/src/org/cx4a/rsense/typing/runtime/Proc.java +100 -0
  87. data/src/org/cx4a/rsense/typing/runtime/RuntimeHelper.java +1339 -0
  88. data/src/org/cx4a/rsense/typing/runtime/SpecialMethod.java +119 -0
  89. data/src/org/cx4a/rsense/typing/runtime/TypeVarMap.java +112 -0
  90. data/src/org/cx4a/rsense/typing/runtime/VertexHolder.java +48 -0
  91. data/src/org/cx4a/rsense/typing/vertex/CallVertex.java +122 -0
  92. data/src/org/cx4a/rsense/typing/vertex/MultipleAsgnVertex.java +23 -0
  93. data/src/org/cx4a/rsense/typing/vertex/PassThroughVertex.java +20 -0
  94. data/src/org/cx4a/rsense/typing/vertex/SValueVertex.java +24 -0
  95. data/src/org/cx4a/rsense/typing/vertex/SplatVertex.java +24 -0
  96. data/src/org/cx4a/rsense/typing/vertex/ToAryVertex.java +24 -0
  97. data/src/org/cx4a/rsense/typing/vertex/TypeVarVertex.java +22 -0
  98. data/src/org/cx4a/rsense/typing/vertex/Vertex.java +221 -0
  99. data/src/org/cx4a/rsense/typing/vertex/YieldVertex.java +70 -0
  100. data/src/org/cx4a/rsense/util/HereDocReader.java +48 -0
  101. data/src/org/cx4a/rsense/util/Logger.java +111 -0
  102. data/src/org/cx4a/rsense/util/NodeUtil.java +198 -0
  103. data/src/org/cx4a/rsense/util/SourceLocation.java +70 -0
  104. data/src/org/cx4a/rsense/util/StringUtil.java +63 -0
  105. data/src/resources/org/cx4a/rsense/rsense.properties +1 -0
  106. data/stubs/1.8/_builtin.rb +3006 -0
  107. data/stubs/1.8/bigdecimal.rb +131 -0
  108. data/stubs/1.8/cgi.rb +257 -0
  109. data/stubs/1.8/date.rb +147 -0
  110. data/stubs/1.8/optparse.rb +113 -0
  111. data/stubs/1.8/rational.rb +47 -0
  112. data/stubs/1.8/set.rb +94 -0
  113. data/stubs/1.8/socket.rb +461 -0
  114. data/stubs/1.8/stringio.rb +129 -0
  115. data/test/data/a file.rb +1 -0
  116. data/test/data/benchmark.rb +12 -0
  117. data/test/data/crlf.rb +5 -0
  118. data/test/data/test.rb +19 -0
  119. data/test/script/all.rsense +2 -0
  120. data/test/script/array_dynamic.rsense +25 -0
  121. data/test/script/block_nested.rsense +7 -0
  122. data/test/script/builtin.rsense +785 -0
  123. data/test/script/class_method_partial_update.rsense +52 -0
  124. data/test/script/class_partial_update.rsense +17 -0
  125. data/test/script/find-definition.rsense +72 -0
  126. data/test/script/method_arg_onearg.rsense +6 -0
  127. data/test/script/method_arg_optional.rsense +7 -0
  128. data/test/script/method_partial_update.rsense +14 -0
  129. data/test/script/method_yield_arrayarg.rsense +8 -0
  130. data/test/script/method_yield_arrayarg_expand.rsense +8 -0
  131. data/test/script/method_yield_arrayarg_splat.rsense +17 -0
  132. data/test/script/misc.rsense +2 -0
  133. data/test/script/proc_higher_order.rsense +22 -0
  134. data/test/script/regression.rsense +95 -0
  135. data/test/script/stdlib.rsense +66 -0
  136. data/test/script/where.rsense +41 -0
  137. metadata +315 -0
@@ -0,0 +1,523 @@
1
+ package org.cx4a.rsense.typing.runtime;
2
+
3
+ import java.util.List;
4
+ import java.util.ArrayList;
5
+ import java.util.Arrays;
6
+
7
+ import org.cx4a.rsense.ruby.Ruby;
8
+ import org.cx4a.rsense.ruby.IRubyObject;
9
+ import org.cx4a.rsense.ruby.RubyClass;
10
+ import org.cx4a.rsense.ruby.RubyModule;
11
+ import org.cx4a.rsense.ruby.Block;
12
+ import org.cx4a.rsense.typing.Graph;
13
+ import org.cx4a.rsense.typing.Template;
14
+ import org.cx4a.rsense.typing.TemplateAttribute;
15
+ import org.cx4a.rsense.typing.TypeSet;
16
+ import org.cx4a.rsense.typing.annotation.TypeExpression;
17
+ import org.cx4a.rsense.typing.annotation.TypeVariable;
18
+ import org.cx4a.rsense.typing.annotation.ClassType;
19
+ import org.cx4a.rsense.typing.annotation.MethodType;
20
+ import org.cx4a.rsense.typing.annotation.TypeIdentity;
21
+ import org.cx4a.rsense.typing.annotation.TypeUnion;
22
+ import org.cx4a.rsense.typing.annotation.TypeOptional;
23
+ import org.cx4a.rsense.typing.annotation.TypeTuple;
24
+ import org.cx4a.rsense.typing.annotation.TypeSplat;
25
+ import org.cx4a.rsense.typing.annotation.TypeApplication;
26
+ import org.cx4a.rsense.typing.annotation.TypeConstraint;
27
+ import org.cx4a.rsense.typing.vertex.Vertex;
28
+ import org.cx4a.rsense.typing.vertex.YieldVertex;
29
+ import org.cx4a.rsense.util.Logger;
30
+
31
+ public class AnnotationResolver {
32
+ public enum Result {
33
+ NOANNOT, UNRESOLVED, RESOLVED,
34
+ };
35
+
36
+ private Graph graph;
37
+ private Ruby runtime;
38
+ private TypeVarMap env;
39
+
40
+ public AnnotationResolver(Graph graph) {
41
+ this.graph = graph;
42
+ this.runtime = graph.getRuntime();
43
+ env = new TypeVarMap();
44
+ }
45
+
46
+ public Result resolveMethodAnnotation(Template template) {
47
+ Method method = template.getMethod();
48
+ if (method.getAnnotations() != null) {
49
+ ClassType classType = RuntimeHelper.getEnclosingClassAnnotation(method.getModule());
50
+ TemplateAttribute attr = template.getAttribute();
51
+ IRubyObject receiver = attr.getMutableReceiver();
52
+ IRubyObject[] args = attr.getMutableArgs();
53
+ Vertex returnVertex = template.getReturnVertex();
54
+
55
+ for (MethodType type : method.getAnnotations()) {
56
+ List<TypeVariable> types = type.getTypes();
57
+ List<TypeConstraint> constraints = type.getConstraints();
58
+ MethodType.Signature sig = type.getSignature();
59
+ if (sig != null) {
60
+ TypeExpression argType = sig.getArgType();
61
+ MethodType.Block block = sig.getBlock();
62
+ TypeExpression returnType = sig.getReturnType();
63
+
64
+ env.clear();
65
+ if (types != null) {
66
+ for (TypeVariable var : types) {
67
+ env.put(var, graph.createFreeVertex());
68
+ }
69
+ }
70
+
71
+ /*
72
+ Logger.debug("resolve annotation for %s", template.getMethod().getName());
73
+ Logger.debug(" class constraints: %s", resolveClassConstraints(template, classType, receiver));
74
+ Logger.debug(" receiver class constraints: %s", resolveReceiverClassConstraints(template, classType, receiver));
75
+ Logger.debug(" method arg: %s", resolveMethodArg(template, classType, argType, receiver, args));
76
+ Logger.debug(" method block: %s", resolveMethodBlock(template, classType, block, receiver));
77
+ Logger.debug(" method constraints: %s", resolveMethodConstraints(template, classType, constraints, receiver));
78
+ Logger.debug(" method return: %s", resolveMethodReturn(template, classType, returnType, receiver));
79
+ */
80
+ if (resolveClassConstraints(template, classType, receiver)
81
+ && resolveReceiverClassConstraints(template, classType, receiver)
82
+ && resolveMethodArg(template, classType, argType, receiver, args)
83
+ && resolveMethodBlock(template, classType, block, receiver)
84
+ && resolveMethodConstraints(template, classType, constraints, receiver)
85
+ && resolveMethodReturn(template, classType, returnType, receiver)) {
86
+ return Result.RESOLVED;
87
+ }
88
+ }
89
+ }
90
+ return Result.UNRESOLVED;
91
+ } else {
92
+ return Result.NOANNOT;
93
+ }
94
+ }
95
+
96
+ public boolean resolveClassConstraints(Template template, ClassType classType, IRubyObject receiver) {
97
+ if (classType == null) { return true; }
98
+
99
+ List<TypeConstraint> constraints = classType.getConstraints();
100
+ if (constraints != null) {
101
+ return resolveMethodConstraints(template, classType, constraints, receiver);
102
+ }
103
+ return true;
104
+ }
105
+
106
+ public boolean resolveReceiverClassConstraints(Template template, ClassType classType, IRubyObject receiver) {
107
+ return receiver == null
108
+ || resolveClassConstraints(template, RuntimeHelper.getClassAnnotation(receiver.getMetaClass()), receiver);
109
+ }
110
+
111
+ public boolean resolveMethodArg(Template template, ClassType classType, TypeExpression argType, IRubyObject receiver, IRubyObject[] args) {
112
+ if (argType == null) {
113
+ // arity check
114
+ return args.length == 0;
115
+ }
116
+
117
+ switch (argType.getType()) {
118
+ case TUPLE: {
119
+ TypeTuple tuple = (TypeTuple) argType;
120
+ List<TypeExpression> list = tuple.getList();
121
+ if (!checkArity(list, args)) {
122
+ //Logger.warn("Wrong number of argument");
123
+ return false;
124
+ }
125
+
126
+ for (int i = 0; i < list.size(); i++) {
127
+ argType = list.get(i);
128
+ IRubyObject arg;
129
+ switch (argType.getType()) {
130
+ case SPLAT: {
131
+ int len = Math.max(args.length - i, 0);
132
+ Vertex[] elements = new Vertex[len];
133
+ for (int j = 0; j < len; j++) {
134
+ elements[j] = graph.createFreeSingleTypeVertex(args[j]);
135
+ }
136
+ arg = RuntimeHelper.createArray(graph, elements);
137
+ break;
138
+ }
139
+ default:
140
+ arg = i < args.length ? args[i] : runtime.getNil();
141
+ }
142
+
143
+ if (!resolveMethodArg(template, classType, argType, receiver, arg)) {
144
+ return false;
145
+ }
146
+ }
147
+
148
+ return true;
149
+ }
150
+ default:
151
+ if (!checkArity(Arrays.asList(argType), args)) {
152
+ //Logger.warn("Wrong number of argument");
153
+ return false;
154
+ }
155
+ IRubyObject arg = args.length > 0 ? args[0] : runtime.getNil();
156
+ return resolveMethodArg(template, classType, argType, receiver, arg);
157
+ }
158
+ }
159
+
160
+ public boolean resolveMethodArg(Template template, ClassType classType, TypeExpression argType, IRubyObject receiver, IRubyObject arg) {
161
+ if (argType == null) { return true; }
162
+
163
+ switch (argType.getType()) {
164
+ case VARIABLE: {
165
+ TypeVariable var = (TypeVariable) argType;
166
+ TypeVarMap typeVarMap = RuntimeHelper.getTypeVarMap(receiver);
167
+ if (classType != null
168
+ && typeVarMap != null
169
+ && classType.containsType(var)) {
170
+ Vertex vertex = typeVarMap.get(var);
171
+ if (vertex == null) {
172
+ vertex = graph.createFreeVertex();
173
+ typeVarMap.put(var, vertex);
174
+ }
175
+ vertex.addType(arg);
176
+ graph.propagateEdges(vertex);
177
+ } else {
178
+ Vertex vertex = env.get(var);
179
+ if (vertex == null) {
180
+ vertex = graph.createFreeVertex();
181
+ env.put(var, vertex);
182
+ }
183
+ vertex.addType(arg);
184
+ graph.propagateEdges(vertex);
185
+ }
186
+ return true;
187
+ }
188
+ case APPLICATION: {
189
+ TypeApplication app = (TypeApplication) argType;
190
+ List<TypeExpression> types = app.getTypes();
191
+ IRubyObject ret = resolveIdentity(template, app.getIdentity());
192
+ if (!(ret instanceof RubyModule) || !arg.isKindOf((RubyModule) ret)) {
193
+ return false;
194
+ } else {
195
+ RubyModule klass = (RubyModule) ret;
196
+ ClassType klassType = RuntimeHelper.getClassAnnotation(klass);
197
+ TypeVarMap typeVarMap = RuntimeHelper.getTypeVarMap(arg);
198
+ if (klassType != null && typeVarMap != null) {
199
+ List<TypeVariable> vars = klassType.getTypes();
200
+ for (int i = 0; i < vars.size(); i++) {
201
+ TypeVariable var = vars.get(i);
202
+ Vertex vertex = typeVarMap.get(var);
203
+ if (i < types.size() && vertex != null) {
204
+ TypeExpression expr = types.get(i);
205
+ for (IRubyObject a : vertex.getTypeSet()) {
206
+ if (!resolveMethodArg(template, klassType, expr, receiver, a)) {
207
+ return false;
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+ }
214
+ return true;
215
+ }
216
+ case SCOPED_IDENTITY:
217
+ case ABSOLUTE_IDENTITY:
218
+ case RELATIVE_IDENTITY: {
219
+ IRubyObject guard = resolveIdentity(template, (TypeIdentity) argType);
220
+ return (guard instanceof RubyClass) && arg.isKindOf((RubyClass) guard);
221
+ }
222
+ case UNION:
223
+ for (TypeExpression expr : (TypeUnion) argType) {
224
+ if (resolveMethodArg(template, classType, expr, receiver, arg)) {
225
+ return true;
226
+ }
227
+ }
228
+ return false;
229
+ case TUPLE: {
230
+ TypeTuple tuple = (TypeTuple) argType;
231
+ for (TypeExpression expr : tuple.getList()) {
232
+ if (resolveMethodArg(template, classType, expr, receiver, arg)) {
233
+ return true;
234
+ }
235
+ }
236
+ return false;
237
+ }
238
+ case SPLAT: {
239
+ TypeSplat splat = (TypeSplat) argType;
240
+ TypeExpression expr = splat.getExpression();
241
+ if (expr == null) {
242
+ return true;
243
+ } else if (expr.getType() == TypeExpression.Type.VARIABLE) {
244
+ return resolveMethodArg(template, classType, expr, receiver, arg);
245
+ } else if (arg instanceof Array) {
246
+ Array array = (Array) arg;
247
+ for (Vertex v : array.getElements()) {
248
+ for (IRubyObject a : v.getTypeSet()) {
249
+ if (!resolveMethodArg(template, classType, expr, receiver, a)) {
250
+ return false;
251
+ }
252
+ }
253
+ }
254
+ return true;
255
+ }
256
+ return false;
257
+ }
258
+ case OPTIONAL: {
259
+ return arg.isNil() ? true : resolveMethodArg(template, classType, ((TypeOptional) argType).getExpression(), receiver, arg);
260
+ }
261
+ case ANY:
262
+ return true;
263
+ default:
264
+ Logger.error("unknown arg type: %s", argType);
265
+ }
266
+ return false;
267
+ }
268
+
269
+ public boolean resolveMethodConstraints(Template template, ClassType classType, List<TypeConstraint> constraints, IRubyObject receiver) {
270
+ if (constraints == null) { return true; }
271
+
272
+ for (TypeConstraint cons : constraints) {
273
+ if (cons.getType() == TypeExpression.Type.SUBTYPE_CONS) {
274
+ TypeExpression lhs = cons.lhs();
275
+ TypeExpression rhs = cons.rhs();
276
+ TypeSet ts = processMethodReturn(template, classType, lhs, receiver);
277
+ if (ts == null) {
278
+ return false;
279
+ } else if (ts.isEmpty() && lhs.getType() == TypeExpression.Type.VARIABLE) {
280
+ // null can be any type
281
+ ts = processMethodReturn(template, classType, rhs, receiver);
282
+ for (IRubyObject arg : ts) {
283
+ if (!resolveMethodArg(template, classType, lhs, receiver, arg)) {
284
+ return false;
285
+ }
286
+ }
287
+ return true;
288
+ }
289
+ for (IRubyObject arg : ts) {
290
+ if (!resolveMethodArg(template, classType, rhs, receiver, arg)) {
291
+ return false;
292
+ }
293
+ }
294
+ }
295
+ }
296
+ return true;
297
+ }
298
+
299
+ public boolean resolveMethodBlock(Template template, ClassType classType, MethodType.Block blockType, IRubyObject receiver) {
300
+ Block block = template.getAttribute().getBlock();
301
+
302
+ if (block == null && blockType == null) {
303
+ return true;
304
+ } else if ((block != null) ^ (blockType != null)) {
305
+ return false;
306
+ }
307
+
308
+ MethodType.Signature blockSig = blockType.getSignature();
309
+ TypeExpression blockArgType = blockSig.getArgType();
310
+ TypeExpression returnArgType = blockSig.getReturnType();
311
+ TypeSet[] args = processMethodBlockArg(template, classType, blockArgType, receiver);
312
+
313
+
314
+ // FIXME checkArity
315
+
316
+ boolean succeed = false;
317
+ Vertex returnVertex;
318
+ if (args.length == 1) {
319
+ YieldVertex vertex = new YieldVertex(null, template, block, graph.createFreeVertex(args[0]), true);
320
+ returnVertex = RuntimeHelper.yield(graph, vertex);
321
+ } else {
322
+ Vertex[] elements = new Vertex[args.length];
323
+ for (int i = 0; i < args.length; i++) {
324
+ elements[i] = graph.createFreeVertex();
325
+ elements[i].addTypes(args[i]);
326
+ }
327
+ YieldVertex vertex = new YieldVertex(null, template, block, graph.createFreeSingleTypeVertex(RuntimeHelper.createArray(graph, elements)), true);
328
+ returnVertex = RuntimeHelper.yield(graph, vertex);
329
+ }
330
+
331
+ if (returnVertex != null) {
332
+ succeed = true;
333
+ for (IRubyObject arg : returnVertex.getTypeSet()) {
334
+ resolveMethodArg(template, classType, returnArgType, receiver, arg);
335
+ }
336
+ }
337
+ return succeed;
338
+ }
339
+
340
+ public TypeSet[] processMethodBlockArg(Template template, ClassType classType, TypeExpression argType, IRubyObject receiver) {
341
+ if (argType == null) { return new TypeSet[0]; }
342
+ List<TypeSet> args = new ArrayList<TypeSet>();
343
+ switch (argType.getType()) {
344
+ case TUPLE: {
345
+ TypeTuple tuple = (TypeTuple) argType;
346
+ for (TypeExpression expr : tuple.getList()) {
347
+ args.add(processMethodReturn(template, classType, expr, receiver));
348
+ }
349
+ break;
350
+ }
351
+ default:
352
+ args.add(processMethodReturn(template, classType, argType, receiver));
353
+ }
354
+
355
+ return args.toArray(new TypeSet[0]);
356
+ }
357
+
358
+ public TypeSet processMethodReturn(Template template, ClassType classType, TypeExpression returnType, IRubyObject receiver) {
359
+ if (returnType == null) { return TypeSet.EMPTY; }
360
+
361
+ TypeSet result = new TypeSet();
362
+ switch (returnType.getType()) {
363
+ case VARIABLE: {
364
+ TypeVariable var = (TypeVariable) returnType;
365
+ if (var.getName().equals("self")) {
366
+ result.add(receiver);
367
+ } else if (var.getName().equals("nil")) {
368
+ result.add(runtime.getNil());
369
+ } else {
370
+ Vertex vertex = env.get(var);
371
+ TypeVarMap typeVarMap = RuntimeHelper.getTypeVarMap(receiver);
372
+ if (vertex != null) {
373
+ result.addAll(vertex.getTypeSet());
374
+ } else if (classType != null
375
+ && typeVarMap != null
376
+ && classType.containsType(var)) {
377
+ vertex = typeVarMap.get(var);
378
+ if (vertex != null) {
379
+ result.addAll(vertex.getTypeSet());
380
+ } else {
381
+ result.add(runtime.getNil());
382
+ }
383
+ }
384
+ }
385
+ return result;
386
+ }
387
+ case APPLICATION: {
388
+ TypeApplication app = (TypeApplication) returnType;
389
+ List<TypeExpression> types = app.getTypes();
390
+ IRubyObject ret = resolveIdentity(template, app.getIdentity());
391
+ if (ret != null && ret instanceof RubyClass) {
392
+ RubyClass klass = (RubyClass) ret;
393
+ ret = graph.newInstanceOf(klass);
394
+ ClassType klassType = RuntimeHelper.getClassAnnotation(klass);
395
+ TypeVarMap typeVarMap = RuntimeHelper.getTypeVarMap(ret);
396
+ if (klassType != null && typeVarMap != null) {
397
+ List<TypeVariable> vars = klassType.getTypes();
398
+ for (int i = 0; i < vars.size(); i++) {
399
+ TypeVariable var = vars.get(i);
400
+ if (i < types.size()) {
401
+ TypeExpression expr = types.get(i);
402
+ TypeSet ts = processMethodReturn(template, classType, expr, receiver);
403
+ Vertex vertex = graph.createFreeVertex();
404
+ vertex.addTypes(ts);
405
+ typeVarMap.put(var, vertex);
406
+ }
407
+ }
408
+ }
409
+ result.add(ret);
410
+ }
411
+ return result;
412
+ }
413
+ case SCOPED_IDENTITY:
414
+ case ABSOLUTE_IDENTITY:
415
+ case RELATIVE_IDENTITY: {
416
+ IRubyObject ret = resolveIdentity(template, (TypeIdentity) returnType);
417
+ if (ret != null && ret instanceof RubyClass) {
418
+ ret = graph.newInstanceOf((RubyClass) ret);
419
+ result.add(ret);
420
+ }
421
+ return result;
422
+ }
423
+ case UNION:
424
+ for (TypeExpression expr : (TypeUnion) returnType) {
425
+ TypeSet ts = processMethodReturn(template, classType, expr, receiver);
426
+ if (ts != null) {
427
+ result.addAll(ts);
428
+ }
429
+ }
430
+ return result;
431
+ case TUPLE: {
432
+ TypeTuple tupleType = (TypeTuple) returnType;
433
+ List<TypeExpression> exprs = tupleType.getList();
434
+ if (exprs != null) {
435
+ Vertex[] elements = new Vertex[exprs.size()];
436
+ for (int i = 0; i < exprs.size(); i++) {
437
+ TypeSet ts = processMethodReturn(template, classType, exprs.get(i), receiver);
438
+ if (ts == null) {
439
+ return result;
440
+ }
441
+ elements[i] = graph.createFreeVertex();
442
+ elements[i].addTypes(ts);
443
+ }
444
+ result.add(RuntimeHelper.createArray(graph, elements));
445
+ }
446
+ return result;
447
+ }
448
+ case ANY:
449
+ case OPTIONAL:
450
+ case SPLAT:
451
+ return result;
452
+ default:
453
+ Logger.error("Unknown return type");
454
+ }
455
+ return null;
456
+ }
457
+
458
+ public boolean resolveMethodReturn(Template template, ClassType classType, TypeExpression returnType, IRubyObject receiver) {
459
+ if (returnType == null) { return true; }
460
+
461
+ TypeSet ts = processMethodReturn(template, classType, returnType, receiver);
462
+ if (ts == null) {
463
+ return false;
464
+ }
465
+
466
+ template.getReturnVertex().addTypes(ts);
467
+ return true;
468
+ }
469
+
470
+ public IRubyObject resolveIdentity(Template template, TypeIdentity ident) {
471
+ return resolveIdentity(template, ident, template.getFrame().getModule());
472
+ }
473
+
474
+ public IRubyObject resolveIdentity(Template template, TypeIdentity ident, RubyModule module) {
475
+ if (ident.getType() == TypeExpression.Type.ABSOLUTE_IDENTITY) {
476
+ return resolveIdentity(template, ident.getPath(), runtime.getObject());
477
+ }
478
+
479
+ IRubyObject value = module.getConstant(ident.getName());
480
+ if (value instanceof VertexHolder) {
481
+ module = null;
482
+ for (IRubyObject t : ((VertexHolder) value).getVertex().getTypeSet()) {
483
+ if (t instanceof RubyModule) {
484
+ module = (RubyModule) t;
485
+ break;
486
+ }
487
+ }
488
+ } else if (value instanceof RubyModule) {
489
+ module = (RubyModule) value;
490
+ } else {
491
+ return value;
492
+ }
493
+
494
+ if (module != null && ident.getType() == TypeExpression.Type.SCOPED_IDENTITY) {
495
+ return resolveIdentity(template, ident.getPath(), module);
496
+ } else {
497
+ return module;
498
+ }
499
+ }
500
+
501
+ public boolean checkArity(List<TypeExpression> list, IRubyObject[] args) {
502
+ int preCount = 0;
503
+ int postCount = 0;
504
+
505
+ for (int i = 0; i < list.size(); i++) {
506
+ TypeExpression argType = list.get(i);
507
+ switch (argType.getType()) {
508
+ case SPLAT:
509
+ return true;
510
+ case OPTIONAL:
511
+ postCount++;
512
+ break;
513
+ default:
514
+ preCount++;
515
+ if (args.length <= i) {
516
+ return false;
517
+ }
518
+ }
519
+ }
520
+
521
+ return preCount + postCount >= args.length;
522
+ }
523
+ }