comparison graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/RubyMethod.java @ 13514:0fbee3eb71f0

Ruby: import project.
author Chris Seaton <chris.seaton@oracle.com>
date Mon, 06 Jan 2014 17:12:09 +0000
parents
children
comparison
equal deleted inserted replaced
13513:64a23ce736a0 13514:0fbee3eb71f0
1 /*
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
4 * redistribute it and/or modify it under the terms of the:
5 *
6 * Eclipse Public License version 1.0
7 * GNU General Public License version 2
8 * GNU Lesser General Public License version 2.1
9 */
10 package com.oracle.truffle.ruby.runtime.methods;
11
12 import com.oracle.truffle.api.*;
13 import com.oracle.truffle.api.frame.*;
14 import com.oracle.truffle.ruby.runtime.*;
15 import com.oracle.truffle.ruby.runtime.core.*;
16 import com.oracle.truffle.ruby.runtime.objects.*;
17
18 /**
19 * Any kind of Ruby method - so normal methods in classes and modules, but also blocks, procs,
20 * lambdas and native methods written in Java.
21 */
22 public class RubyMethod {
23
24 private final SourceSection sourceSection;
25 private final RubyModule declaringModule;
26 private final UniqueMethodIdentifier uniqueIdentifier;
27 private final String intrinsicName;
28 private final String name;
29 private final Visibility visibility;
30 private final boolean undefined;
31
32 private final MethodImplementation implementation;
33
34 public RubyMethod(SourceSection sourceSection, RubyModule declaringModule, UniqueMethodIdentifier uniqueIdentifier, String intrinsicName, String name, Visibility visibility, boolean undefined,
35 MethodImplementation implementation) {
36 this.sourceSection = sourceSection;
37 this.declaringModule = declaringModule;
38 this.uniqueIdentifier = uniqueIdentifier;
39 this.intrinsicName = intrinsicName;
40 this.name = name;
41 this.visibility = visibility;
42 this.undefined = undefined;
43 this.implementation = implementation;
44 }
45
46 public Object call(PackedFrame caller, Object self, RubyProc block, Object... args) {
47 assert RubyContext.shouldObjectBeVisible(self);
48 assert RubyContext.shouldObjectsBeVisible(args);
49
50 final Object result = implementation.call(caller, self, block, args);
51
52 assert RubyContext.shouldObjectBeVisible(result);
53
54 return result;
55 }
56
57 public SourceSection getSourceSection() {
58 return sourceSection;
59 }
60
61 public UniqueMethodIdentifier getUniqueIdentifier() {
62 return uniqueIdentifier;
63 }
64
65 public String getIntrinsicName() {
66 return intrinsicName;
67 }
68
69 public String getName() {
70 return name;
71 }
72
73 public Visibility getVisibility() {
74 return visibility;
75 }
76
77 public boolean isUndefined() {
78 return undefined;
79 }
80
81 public MethodImplementation getImplementation() {
82 return implementation;
83 }
84
85 public RubyMethod withNewName(String newName) {
86 if (newName.equals(name)) {
87 return this;
88 }
89
90 return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, newName, visibility, undefined, implementation);
91 }
92
93 public RubyMethod withNewVisibility(Visibility newVisibility) {
94 if (newVisibility == visibility) {
95 return this;
96 }
97
98 return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, name, newVisibility, undefined, implementation);
99 }
100
101 public RubyMethod withDeclaringModule(RubyModule newDeclaringModule) {
102 if (newDeclaringModule == declaringModule) {
103 return this;
104 }
105
106 return new RubyMethod(sourceSection, newDeclaringModule, uniqueIdentifier, intrinsicName, name, visibility, undefined, implementation);
107 }
108
109 public RubyMethod undefined() {
110 if (undefined) {
111 return this;
112 }
113
114 return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, name, visibility, true, implementation);
115 }
116
117 public boolean isVisibleTo(RubyBasicObject caller) {
118 if (caller instanceof RubyModule) {
119 if (isVisibleTo((RubyModule) caller)) {
120 return true;
121 }
122 }
123
124 if (isVisibleTo(caller.getRubyClass())) {
125 return true;
126 }
127
128 if (isVisibleTo(caller.getSingletonClass())) {
129 return true;
130 }
131
132 return false;
133 }
134
135 private boolean isVisibleTo(RubyModule module) {
136 switch (visibility) {
137 case PUBLIC:
138 return true;
139
140 case PROTECTED:
141 return true;
142
143 case PRIVATE:
144 if (module == declaringModule) {
145 return true;
146 }
147
148 if (module.getSingletonClass() == declaringModule) {
149 return true;
150 }
151
152 if (module.getParentModule() != null && isVisibleTo(module.getParentModule())) {
153 return true;
154 }
155
156 return false;
157
158 default:
159 return false;
160 }
161 }
162
163 @Override
164 public String toString() {
165 return implementation.toString();
166 }
167
168 }