annotate graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java @ 13942:1ee27cd07ed0

Make code extensible
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 12 Feb 2014 10:25:29 -0800
parents 22bf5a8ba9eb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
1 /*
13732
fbf448929260 Ruby: remove some prototyping code no longer needed
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents: 13645
diff changeset
2 * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
4 * redistribute it and/or modify it under the terms of the:
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
5 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
6 * Eclipse Public License version 1.0
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
7 * GNU General Public License version 2
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
8 * GNU Lesser General Public License version 2.1
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
9 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
10 package com.oracle.truffle.ruby.nodes.core;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
11
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
12 import java.util.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
13
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
14 import com.oracle.truffle.api.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
15 import com.oracle.truffle.api.dsl.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
16 import com.oracle.truffle.api.frame.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
17 import com.oracle.truffle.api.nodes.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
18 import com.oracle.truffle.ruby.nodes.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
19 import com.oracle.truffle.ruby.nodes.control.*;
13918
22bf5a8ba9eb Ruby: restore prototype debugger.
Chris Seaton <chris.seaton@oracle.com>
parents: 13736
diff changeset
20 import com.oracle.truffle.ruby.nodes.debug.*;
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
21 import com.oracle.truffle.ruby.nodes.methods.arguments.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
22 import com.oracle.truffle.ruby.nodes.objects.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
23 import com.oracle.truffle.ruby.runtime.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
24 import com.oracle.truffle.ruby.runtime.core.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
25 import com.oracle.truffle.ruby.runtime.methods.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
26
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
27 public abstract class CoreMethodNodeManager {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
28
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
29 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
30 * Register all the nodes that represent core methods as methods with their respective classes,
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
31 * given the Object class object, which should already be initialized with all the core classes.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
32 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
33 public static void addMethods(RubyClass rubyObjectClass) {
13942
1ee27cd07ed0 Make code extensible
Christian Wimmer <christian.wimmer@oracle.com>
parents: 13918
diff changeset
34 addMethods(rubyObjectClass, getMethods());
1ee27cd07ed0 Make code extensible
Christian Wimmer <christian.wimmer@oracle.com>
parents: 13918
diff changeset
35 }
1ee27cd07ed0 Make code extensible
Christian Wimmer <christian.wimmer@oracle.com>
parents: 13918
diff changeset
36
1ee27cd07ed0 Make code extensible
Christian Wimmer <christian.wimmer@oracle.com>
parents: 13918
diff changeset
37 public static void addMethods(RubyClass rubyObjectClass, List<MethodDetails> methods) {
1ee27cd07ed0 Make code extensible
Christian Wimmer <christian.wimmer@oracle.com>
parents: 13918
diff changeset
38 // Same as above, but allows passing of a specific list of core methods.
1ee27cd07ed0 Make code extensible
Christian Wimmer <christian.wimmer@oracle.com>
parents: 13918
diff changeset
39 // This allows extending Truffle-Ruby with non-standard Core Method.
1ee27cd07ed0 Make code extensible
Christian Wimmer <christian.wimmer@oracle.com>
parents: 13918
diff changeset
40 for (MethodDetails methodDetails : methods) {
13645
497fada09efb Ruby: remove versioning.
Chris Seaton <chris.seaton@oracle.com>
parents: 13514
diff changeset
41 addMethod(rubyObjectClass, methodDetails);
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
42 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
43 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
44
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
45 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
46 * Collect up all the core method nodes. Abstracted to allow the SVM to implement at compile
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
47 * type.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
48 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
49 public static List<MethodDetails> getMethods() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
50 final List<MethodDetails> methods = new ArrayList<>();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
51 getMethods(methods, ArrayNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
52 getMethods(methods, BasicObjectNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
53 getMethods(methods, BignumNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
54 getMethods(methods, ClassNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
55 getMethods(methods, ContinuationNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
56 getMethods(methods, ComparableNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
57 getMethods(methods, DirNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
58 getMethods(methods, ExceptionNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
59 getMethods(methods, FalseClassNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
60 getMethods(methods, FiberNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
61 getMethods(methods, FileNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
62 getMethods(methods, FixnumNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
63 getMethods(methods, FloatNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
64 getMethods(methods, HashNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
65 getMethods(methods, KernelNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
66 getMethods(methods, MainNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
67 getMethods(methods, MatchDataNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
68 getMethods(methods, MathNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
69 getMethods(methods, ModuleNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
70 getMethods(methods, NilClassNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
71 getMethods(methods, ObjectNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
72 getMethods(methods, ObjectSpaceNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
73 getMethods(methods, ProcessNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
74 getMethods(methods, ProcNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
75 getMethods(methods, RangeNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
76 getMethods(methods, RegexpNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
77 getMethods(methods, SignalNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
78 getMethods(methods, StringNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
79 getMethods(methods, StructNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
80 getMethods(methods, SymbolNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
81 getMethods(methods, ThreadNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
82 getMethods(methods, TimeNodesFactory.getFactories());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
83 getMethods(methods, TrueClassNodesFactory.getFactories());
13918
22bf5a8ba9eb Ruby: restore prototype debugger.
Chris Seaton <chris.seaton@oracle.com>
parents: 13736
diff changeset
84 getMethods(methods, DebugNodesFactory.getFactories());
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
85 return methods;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
86 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
87
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
88 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
89 * Collect up the core methods created by a factory.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
90 */
13942
1ee27cd07ed0 Make code extensible
Christian Wimmer <christian.wimmer@oracle.com>
parents: 13918
diff changeset
91 public static void getMethods(List<MethodDetails> methods, List<? extends NodeFactory<? extends CoreMethodNode>> nodeFactories) {
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
92 for (NodeFactory<? extends RubyNode> nodeFactory : nodeFactories) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
93 final GeneratedBy generatedBy = nodeFactory.getClass().getAnnotation(GeneratedBy.class);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
94 final Class<?> nodeClass = generatedBy.value();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
95 final CoreClass classAnnotation = nodeClass.getEnclosingClass().getAnnotation(CoreClass.class);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
96 final CoreMethod methodAnnotation = nodeClass.getAnnotation(CoreMethod.class);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
97 methods.add(new MethodDetails(classAnnotation, methodAnnotation, nodeFactory));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
98 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
99 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
100
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
101 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
102 * Take a core method node factory, the annotations for the class and method, and add it as a
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
103 * method on the correct class.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
104 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
105 private static void addMethod(RubyClass rubyObjectClass, MethodDetails methodDetails) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
106 assert rubyObjectClass != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
107 assert methodDetails != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
108
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
109 final RubyContext context = rubyObjectClass.getContext();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
110
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
111 RubyModule module;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
112
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
113 if (methodDetails.getClassAnnotation().name().equals("main")) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
114 module = context.getCoreLibrary().getMainObject().getSingletonClass();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
115 } else {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
116 module = (RubyModule) rubyObjectClass.lookupConstant(methodDetails.getClassAnnotation().name());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
117 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
118
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
119 assert module != null : methodDetails.getClassAnnotation().name();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
120
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
121 final List<String> names = Arrays.asList(methodDetails.getMethodAnnotation().names());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
122 assert names.size() >= 1;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
123
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
124 final String canonicalName = names.get(0);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
125 final List<String> aliases = names.subList(1, names.size());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
126
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
127 final UniqueMethodIdentifier uniqueIdentifier = new UniqueMethodIdentifier();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
128 final Visibility visibility = Visibility.PUBLIC;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
129
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
130 final RubyRootNode pristineRootNode = makeGenericMethod(context, methodDetails);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
131 final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
132
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
133 final String intrinsicName = methodDetails.getClassAnnotation().name() + "#" + canonicalName;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
134
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
135 final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRootNode, true,
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
136 methodDetails.getMethodAnnotation().appendCallNode());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
137 final RubyMethod method = new RubyMethod(pristineRootNode.getSourceSection(), module, uniqueIdentifier, intrinsicName, canonicalName, visibility, false, methodImplementation);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
138
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
139 module.addMethod(method);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
140
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
141 if (methodDetails.getMethodAnnotation().isModuleMethod()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
142 module.getSingletonClass().addMethod(method);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
143 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
144
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
145 for (String alias : aliases) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
146 final RubyMethod withAlias = method.withNewName(alias);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
147
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
148 module.addMethod(withAlias);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
149
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
150 if (methodDetails.getMethodAnnotation().isModuleMethod()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
151 module.getSingletonClass().addMethod(withAlias);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
152 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
153 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
154 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
155
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
156 private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails methodDetails) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
157 final SourceSection sourceSection = new CoreSourceSection(methodDetails.getClassAnnotation().name() + "#" + methodDetails.getMethodAnnotation().names()[0]);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
158
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
159 final Arity arity = new Arity(methodDetails.getMethodAnnotation().minArgs(), methodDetails.getMethodAnnotation().maxArgs());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
160
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
161 final List<RubyNode> argumentsNodes = new ArrayList<>();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
162
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
163 if (methodDetails.getMethodAnnotation().needsSelf()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
164 argumentsNodes.add(new SelfNode(context, sourceSection));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
165 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
166
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
167 if (methodDetails.getMethodAnnotation().isSplatted()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
168 argumentsNodes.add(new ReadAllArgumentsNode(context, sourceSection));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
169 } else {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
170 assert arity.getMaximum() != Arity.NO_MAXIMUM;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
171
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
172 for (int n = 0; n < arity.getMaximum(); n++) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
173 argumentsNodes.add(new ReadPreArgumentNode(context, sourceSection, n, true));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
174 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
175 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
176
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
177 if (methodDetails.getMethodAnnotation().needsBlock()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
178 argumentsNodes.add(new ReadBlockArgumentNode(context, sourceSection, true));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
179 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
180
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
181 final RubyNode methodNode = methodDetails.getNodeFactory().createNode(context, sourceSection, argumentsNodes.toArray(new RubyNode[argumentsNodes.size()]));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
182 final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, arity);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
183 final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, methodNode);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
184
13706
232eb6708943 Ruby: required fixes for moving FrameDescriptor to the RootNode.
Christian Humer <christian.humer@gmail.com>
parents: 13645
diff changeset
185 return new RubyRootNode(sourceSection, null, methodDetails.getClassAnnotation().name() + "#" + methodDetails.getMethodAnnotation().names()[0] + "(core)", block);
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
186 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
187
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
188 public static class MethodDetails {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
189
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
190 private final CoreClass classAnnotation;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
191 private final CoreMethod methodAnnotation;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
192 private final NodeFactory<? extends RubyNode> nodeFactory;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
193
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
194 public MethodDetails(CoreClass classAnnotation, CoreMethod methodAnnotation, NodeFactory<? extends RubyNode> nodeFactory) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
195 assert classAnnotation != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
196 assert methodAnnotation != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
197 assert nodeFactory != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
198 this.classAnnotation = classAnnotation;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
199 this.methodAnnotation = methodAnnotation;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
200 this.nodeFactory = nodeFactory;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
201 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
202
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
203 public CoreClass getClassAnnotation() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
204 return classAnnotation;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
205 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
206
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
207 public CoreMethod getMethodAnnotation() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
208 return methodAnnotation;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
209 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
210
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
211 public NodeFactory<? extends RubyNode> getNodeFactory() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
212 return nodeFactory;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
213 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
214
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
215 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
216
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
217 }