org.jruby.embed.variable.VariableInterceptor Maven / Gradle / Ivy
/**
* **** BEGIN LICENSE BLOCK *****
* Version: CPL 1.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Common Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/cpl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Copyright (C) 2009-2011 Yoko Harada
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the CPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the CPL, the GPL or the LGPL.
* **** END LICENSE BLOCK *****
*/
package org.jruby.embed.variable;
import java.util.List;
import org.jruby.Ruby;
import org.jruby.RubyObject;
import org.jruby.embed.internal.BiVariableMap;
import org.jruby.embed.LocalVariableBehavior;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.scope.ManyVarsDynamicScope;
/**
* This class is responsible to local variable behavior dependent processing.
*
* @author Yoko Harada
*/
public class VariableInterceptor {
//private LocalVariableBehavior behavior;
/**
* Constructs an instance with a given local variable behavior.
*
* @param behavior local variable behavior
*/
//public VariableInterceptor(LocalVariableBehavior behavior) {
// this.behavior = behavior;
//}
//public LocalVariableBehavior getLocalVariableBehavior() {
// return behavior;
//}
/**
* Returns an appropriate type of a variable instance to the specified local
* variable behavior.
*
* @param runtime Ruby runtime
* @param name variable name
* @param value variable value
* @return an appropriate type of the variable instance.
*/
public static BiVariable getVariableInstance(LocalVariableBehavior behavior, RubyObject receiver, String name, Object... value) {
if (value == null || value.length < 1) {
return null;
}
if ("ARGV".equals(name)) {
return Argv.getInstance(receiver, name, value);
}
switch (behavior) {
case GLOBAL:
return LocalGlobalVariable.getInstance(receiver, name, value);
case BSF:
BiVariable[] bEntries = {
PersistentLocalVariable.getInstance(receiver, name, value),
GlobalVariable.getInstance(receiver, name, value)
};
return resolve(bEntries);
case PERSISTENT:
BiVariable[] pEntries = {
GlobalVariable.getInstance(receiver, name, value),
InstanceVariable.getInstance(receiver, name, value),
ClassVariable.getInstance(receiver, name, value),
Constant.getInstance(receiver, name, value),
PersistentLocalVariable.getInstance(receiver, name, value)
};
return resolve(pEntries);
default:
BiVariable[] tEntries = {
GlobalVariable.getInstance(receiver, name, value),
InstanceVariable.getInstance(receiver, name, value),
ClassVariable.getInstance(receiver, name, value),
Constant.getInstance(receiver, name, value),
TransientLocalVariable.getInstance(receiver, name, value)
};
return resolve(tEntries);
}
}
private static BiVariable resolve(BiVariable[] entries) {
for (BiVariable e : entries) {
if (e != null) {
return e;
}
}
return null;
}
/**
* Injects variable values from Java to Ruby just before an evaluation or
* method invocation.
*
* @param map a variable map that has name-value pairs to be injected
* @param runtime Ruby runtime
* @param scope scope to inject local variable values
* @param depth depth of a frame to inject local variable values
* @param receiver a receiver when the script has been evaluated once
*/
public static void inject(BiVariableMap map, Ruby runtime, ManyVarsDynamicScope scope, int depth, IRubyObject receiver) {
// lvar might not be given while parsing but be given when evaluating.
// to avoid ArrayIndexOutOfBoundsException, checks the length of scope.getValues()
if (scope != null && scope.getValues().length > 0) {
IRubyObject[] values4Injection = map.getLocalVarValues();
if (values4Injection != null && values4Injection.length > 0) {
for (int i = 0; i < values4Injection.length; i++) {
scope.setValue(i, values4Injection[i], depth);
}
}
}
List variables = map.getVariables();
if (variables == null) return;
for (int i=0; i variables, Ruby runtime) {
if (variables == null) return;
if (LocalVariableBehavior.GLOBAL == behavior) {
for (int i = 0; i < variables.size(); i++) {
if (BiVariable.Type.LocalGlobalVariable == variables.get(i).getType()) {
runtime.getGlobalVariables().set("$" + variables.get(i).getName(), runtime.getNil());
}
}
}
}
/**
* Clears local variables form the variable map so that old local variable
* name-value pairs are not to be used in successive evaluations.
*
* @param varNames variable name list to be cleared
* @param variables variable value list to be cleared
*/
public static void terminateLocalVariables(LocalVariableBehavior behavior, List varNames, List variables) {
if (variables == null) return;
if (LocalVariableBehavior.TRANSIENT == behavior) {
for (int i = 0; i < variables.size(); i++) {
if (BiVariable.Type.LocalVariable == variables.get(i).getType()) {
varNames.remove(i);
variables.remove(i);
}
}
}
}
/**
* Checks the given name is whether a legal Ruby variable/constant name or not.
*
* @param name a given name to be checked
* @return true when the name is a legal Ruby variable/constant name, otherwise false.
*/
public static boolean isKindOfRubyVariable(LocalVariableBehavior behavior, String name) {
if ("ARGV".equals(name)) return true;
switch (behavior) {
case GLOBAL:
return LocalGlobalVariable.isValidName(name);
case BSF:
if (PersistentLocalVariable.isValidName(name)) {
return true;
} else if (GlobalVariable.isValidName(name)) {
return true;
}
return false;
case PERSISTENT:
if (GlobalVariable.isValidName(name)) {
return true;
} else if (PersistentLocalVariable.isValidName(name)) {
return true;
} else if (InstanceVariable.isValidName(name)) {
return true;
} else if (Constant.isValidName(name)) {
return true;
} else if (ClassVariable.isValidName(name)) {
return true;
}
return false;
default:
if (GlobalVariable.isValidName(name)) {
return true;
} else if (TransientLocalVariable.isValidName(name)) {
return true;
} else if (InstanceVariable.isValidName(name)) {
return true;
} else if (Constant.isValidName(name)) {
return true;
} else if (ClassVariable.isValidName(name)) {
return true;
}
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy