rsense-core 0.5.0

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