Skip to content

Commit

Permalink
Showing 17 changed files with 525 additions and 293 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -98,3 +98,4 @@ core/.classpath
core/.gitignore
core/.project
core/.settings
core/.apt_generated
265 changes: 16 additions & 249 deletions core/src/main/java/org/jruby/RubyString.java

Large diffs are not rendered by default.

27 changes: 13 additions & 14 deletions core/src/main/java/org/jruby/truffle/nodes/control/AndNode.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
* Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
@@ -9,16 +9,14 @@
*/
package org.jruby.truffle.nodes.control;

import com.oracle.truffle.api.*;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.*;
import org.jruby.truffle.nodes.*;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeFactory;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.RubyContext;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;

/**
* Represents a Ruby {@code and} or {@code &&} expression.
@@ -28,6 +26,7 @@ public class AndNode extends RubyNode {
@Child protected RubyNode left;
@Child protected BooleanCastNode leftCast;
@Child protected RubyNode right;
private final ConditionProfile conditionProfile = ConditionProfile.createCountingProfile();

public AndNode(RubyContext context, SourceSection sourceSection, RubyNode left, RubyNode right) {
super(context, sourceSection);
@@ -39,12 +38,12 @@ public AndNode(RubyContext context, SourceSection sourceSection, RubyNode left,
@Override
public Object execute(VirtualFrame frame) {
final Object leftValue = left.execute(frame);

if (!leftCast.executeBoolean(frame, leftValue)) {
boolean leftBoolean = leftCast.executeBoolean(frame, leftValue);
if (conditionProfile.profile(leftBoolean)) {
// Right expression evaluated and returned if left expression returns true.
return right.execute(frame);
} else {
return leftValue;
}

return right.execute(frame);
}

}
39 changes: 37 additions & 2 deletions core/src/main/java/org/jruby/truffle/nodes/core/FileNodes.java
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import jnr.posix.FileStat;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.core.RubyArray;
@@ -65,7 +66,7 @@ public RubyNilClass close(RubyFile file) {

}

@CoreMethod(names = "delete", onSingleton = true, required = 1)
@CoreMethod(names = { "delete", "unlink" }, onSingleton = true, required = 1)
public abstract static class DeleteNode extends CoreMethodNode {

public DeleteNode(RubyContext context, SourceSection sourceSection) {
@@ -87,7 +88,7 @@ public int delete(RubyString file) {

}

@CoreMethod(names = "directory?", onSingleton = true, optional = 1)
@CoreMethod(names = "directory?", onSingleton = true, required = 1)
public abstract static class DirectoryNode extends CoreMethodNode {

public DirectoryNode(RubyContext context, SourceSection sourceSection) {
@@ -442,6 +443,40 @@ public Object read(RubyString file) {

}

@CoreMethod(names = "symlink?", onSingleton = true, required = 1)
public abstract static class SymlinkQueryNode extends CoreMethodNode {

public SymlinkQueryNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public SymlinkQueryNode(SymlinkQueryNode prev) {
super(prev);
}

@Specialization
public boolean symlinkQuery(RubyString fileName) {
notDesignedForCompilation();

try {
// Note: We can't use file.exists() to check whether the symlink
// exists or not, because that method returns false for existing
// but broken symlink. So, we try without the existence check,
// but in the try-catch block.
// MRI behavior: symlink? on broken symlink should return true.
FileStat stat = getContext().getRuntime().getPosix().allocateStat();

if (getContext().getRuntime().getPosix().lstat(fileName.toString(), stat) < 0) {
stat = null;
}

return (stat != null && stat.isSymlink());
} catch (SecurityException re) {
return false;
}
}
}

@CoreMethod(names = "write", required = 1)
public abstract static class WriteNode extends CoreMethodNode {

187 changes: 186 additions & 1 deletion core/src/main/java/org/jruby/truffle/nodes/core/StringNodes.java
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
import org.joni.Matcher;
import org.joni.Option;
import org.joni.Region;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.runtime.Visibility;
@@ -738,6 +739,29 @@ public int getByte(RubyString string, int index) {
}
}

@CoreMethod(names = "include?", required = 1)
public abstract static class IncludeQueryNode extends CoreMethodNode {

public IncludeQueryNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public IncludeQueryNode(IncludeQueryNode prev) {
super(prev);
}

@Specialization
public boolean includeQuery(RubyString string, RubyString otherString) {
notDesignedForCompilation();

int foundIndex = StringSupport.index(string, string.getBytes(), string.length(),
otherString, otherString.getBytes(), otherString.length(),
0, string.getBytes().getEncoding());

return foundIndex != -1;
}
}

@CoreMethod(names = "inspect")
public abstract static class InspectNode extends CoreMethodNode {

@@ -809,6 +833,69 @@ public Object initializeCopy(RubyString self, RubyString from) {

}

@CoreMethod(names = "insert", required = 2, lowerFixnumParameters = 0)
public abstract static class InsertNode extends CoreMethodNode {

@Child protected ConcatNode concatNode;
@Child protected GetIndexNode getIndexNode;

public InsertNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
concatNode = StringNodesFactory.ConcatNodeFactory.create(context, sourceSection, new RubyNode[]{});
getIndexNode = StringNodesFactory.GetIndexNodeFactory.create(context, sourceSection, new RubyNode[]{});
}

public InsertNode(InsertNode prev) {
super(prev);
concatNode = prev.concatNode;
getIndexNode = prev.getIndexNode;
}

@Specialization
public RubyString insert(RubyString string, int index, RubyString otherString) {
notDesignedForCompilation();

if (string.isFrozen()) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().frozenError("String", this));
}

if (index == -1) {
concatNode.concat(string, otherString);

return string;

} else if (index < 0) {
// Incrementing first seems weird, but MRI does it and it's significant because it uses the modified
// index value in its error messages. This seems wrong, but we should be compatible.
index++;

if (-index > string.length()) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().indexError(String.format("index %d out of string", index), this));
}

index = index + string.length();

} else if (index > string.length()) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().indexError(String.format("index %d out of string", index), this));
}

RubyString firstPart = getIndexNode.getIndex(string, 0, index);
RubyString secondPart = getIndexNode.getIndex(string, index, string.length());

RubyString concatenated = concatNode.concat(concatNode.concat(firstPart, otherString), secondPart);

string.set(concatenated.getBytes());

return string;
}
}

@CoreMethod(names = "ljust", required = 1, optional = 1, lowerFixnumParameters = 0)
public abstract static class LjustNode extends CoreMethodNode {

@@ -879,6 +966,52 @@ public int ord(RubyString string) {
}
}

@CoreMethod(names = "rindex", required = 1, optional = 1, lowerFixnumParameters = 1)
public abstract static class RindexNode extends CoreMethodNode {

public RindexNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public RindexNode(RindexNode prev) {
super(prev);
}

@Specialization
public Object rindex(RubyString string, RubyString subString, @SuppressWarnings("unused") UndefinedPlaceholder endPosition) {
notDesignedForCompilation();

return rindex(string, subString, string.length());
}

@Specialization
public Object rindex(RubyString string, RubyString subString, int endPosition) {
notDesignedForCompilation();

int normalizedEndPosition = endPosition;

if (endPosition < 0) {
normalizedEndPosition = endPosition + string.length();

if (normalizedEndPosition < 0) {
return getContext().getCoreLibrary().getNilObject();
}
} else if (endPosition > string.length()) {
normalizedEndPosition = string.length();
}

int result = StringSupport.rindex(string.getBytes(), string.length(), subString.getBytes(), subString.length(),
normalizedEndPosition, subString, string.getBytes().getEncoding()
);

if (result >= 0) {
return result;
} else {
return getContext().getCoreLibrary().getNilObject();
}
}
}

@CoreMethod(names = "rjust", required = 1, optional = 1, lowerFixnumParameters = 0)
public abstract static class RjustNode extends CoreMethodNode {

@@ -1032,7 +1165,7 @@ public SizeNode(SizeNode prev) {

@Specialization
public int size(RubyString string) {
return string.getBytes().getRealSize();
return string.length();
}
}

@@ -1116,6 +1249,58 @@ public RubyString sub(RubyString string, RubyRegexp regexp, RubyString replaceme
}
}

@CoreMethod(names = "succ")
public abstract static class SuccNode extends CoreMethodNode {

public SuccNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public SuccNode(SuccNode prev) {
super(prev);
}

@Specialization
public RubyString succ(RubyString string) {
notDesignedForCompilation();

if (string.length() > 0) {
return getContext().makeString(StringSupport.succCommon(string.getBytes()));
} else {
return getContext().makeString("");
}
}
}

@CoreMethod(names = "succ!")
public abstract static class SuccBangNode extends CoreMethodNode {

public SuccBangNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public SuccBangNode(SuccBangNode prev) {
super(prev);
}

@Specialization
public RubyString succBang(RubyString string) {
notDesignedForCompilation();

if (string.isFrozen()) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().frozenError("String", this));
}

if (string.length() > 0) {
string.set(StringSupport.succCommon(string.getBytes()));
}

return string;
}
}

@CoreMethod(names = "sum")
public abstract static class SumNode extends CoreMethodNode {

Original file line number Diff line number Diff line change
@@ -136,6 +136,12 @@ public long callLongFixnum(
this));
}

/**
* Check if a specific method is defined on the receiver object.
* This check is "static" and should only be used in a few VM operations.
* In many cases, a dynamic call to Ruby's respond_to? should be used instead.
* Similar to MRI rb_check_funcall().
*/
public boolean doesRespondTo(
VirtualFrame frame,
Object methodName,
21 changes: 19 additions & 2 deletions core/src/main/java/org/jruby/truffle/runtime/core/RubyString.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
* Copyright (c) 2013, 2014, 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
@@ -17,12 +17,13 @@
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.util.ByteList;
import org.jruby.util.CodeRangeable;
import org.jruby.util.StringSupport;

/**
* Represents the Ruby {@code String} class.
*/
public class RubyString extends RubyBasicObject {
public class RubyString extends RubyBasicObject implements CodeRangeable {

private ByteList bytes;

@@ -150,6 +151,10 @@ public int hashCode() {
return bytes.hashCode();
}

public int length() {
return getBytes().getRealSize();
}

public int normaliseIndex(int index) {
return RubyArray.normaliseIndex(bytes.length(), index);
}
@@ -158,6 +163,18 @@ public int clampExclusiveIndex(int index) {
return RubyArray.clampExclusiveIndex(bytes.length(), index);
}

@Override
public int getCodeRange() {
// TODO (nirvdrum Jan. 2, 2015): Make this work with the String's real code range, not just a stubbed value.
return StringSupport.CR_VALID;
}

@Override
public int scanForCodeRange() {
// TODO (nirvdrum Jan. 2, 2015): Make this work with the String's real code range, not just a stubbed value.
return getCodeRange();
}

public static class StringAllocator implements Allocator {

@Override
16 changes: 16 additions & 0 deletions core/src/main/java/org/jruby/util/CodeRangeable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/

package org.jruby.util;

public interface CodeRangeable {
public int getCodeRange();
public int scanForCodeRange();
}
231 changes: 231 additions & 0 deletions core/src/main/java/org/jruby/util/StringSupport.java
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@

import org.jcodings.Encoding;
import org.jcodings.ascii.AsciiTables;
import org.jcodings.constants.CharacterType;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jcodings.util.IntHash;
@@ -834,6 +835,35 @@ public static int countCommon19(ByteList value, Ruby runtime, boolean[] table, T
return i;
}

/**
* rb_str_rindex_m
*/
public static int rindex(ByteList source, int sourceLen, ByteList subString, int subLen, int endPosition, CodeRangeable subStringCodeRangeable, Encoding enc) {
if (subStringCodeRangeable.scanForCodeRange() == CR_BROKEN) return -1;

if (sourceLen < subLen) return -1;
if (sourceLen - endPosition < subLen) endPosition = sourceLen - subLen;
if (sourceLen == 0) return endPosition;

byte[]bytes = source.getUnsafeBytes();
int p = source.getBegin();
int end = p + source.getRealSize();

byte[]sbytes = subString.bytes();
subLen = subString.getRealSize();

int s = nth(enc, bytes, p, end, endPosition);
while (s >= 0) {
if (ByteList.memcmp(bytes, s, sbytes, 0, subLen) == 0) return endPosition;

if (endPosition == 0) break;
endPosition--;

s = enc.prevCharHead(bytes, p, s, end);
}
return -1;
}

/**
* rb_str_tr / rb_str_tr_bang
*/
@@ -961,4 +991,205 @@ public static int trNext(TR t, Ruby runtime, Encoding enc) {
}
}
}

/**
* succ
*/

public static enum NeighborChar {NOT_CHAR, FOUND, WRAPPED}

public static ByteList succCommon(ByteList original) {
byte carry[] = new byte[org.jcodings.Config.ENC_CODE_TO_MBC_MAXLEN];
int carryP = 0;
carry[0] = 1;
int carryLen = 1;

ByteList valueCopy = new ByteList(original);
valueCopy.setEncoding(original.getEncoding());
Encoding enc = original.getEncoding();
int p = valueCopy.getBegin();
int end = p + valueCopy.getRealSize();
int s = end;
byte[]bytes = valueCopy.getUnsafeBytes();

NeighborChar neighbor = NeighborChar.FOUND;
int lastAlnum = -1;
boolean alnumSeen = false;
while ((s = enc.prevCharHead(bytes, p, s, end)) != -1) {
if (neighbor == NeighborChar.NOT_CHAR && lastAlnum != -1) {
if (ASCIIEncoding.INSTANCE.isAlpha(bytes[lastAlnum] & 0xff) ?
ASCIIEncoding.INSTANCE.isDigit(bytes[s] & 0xff) :
ASCIIEncoding.INSTANCE.isDigit(bytes[lastAlnum] & 0xff) ?
ASCIIEncoding.INSTANCE.isAlpha(bytes[s] & 0xff) : false) {
s = lastAlnum;
break;
}
}

int cl = preciseLength(enc, bytes, s, end);
if (cl <= 0) continue;
switch (neighbor = succAlnumChar(enc, bytes, s, cl, carry, 0)) {
case NOT_CHAR: continue;
case FOUND: return valueCopy;
case WRAPPED: lastAlnum = s;
}
alnumSeen = true;
carryP = s - p;
carryLen = cl;
}

if (!alnumSeen) {
s = end;
while ((s = enc.prevCharHead(bytes, p, s, end)) != -1) {
int cl = preciseLength(enc, bytes, s, end);
if (cl <= 0) continue;
neighbor = succChar(enc, bytes, s, cl);
if (neighbor == NeighborChar.FOUND) return valueCopy;
if (preciseLength(enc, bytes, s, s + 1) != cl) succChar(enc, bytes, s, cl); /* wrapped to \0...\0. search next valid char. */
if (!enc.isAsciiCompatible()) {
System.arraycopy(bytes, s, carry, 0, cl);
carryLen = cl;
}
carryP = s - p;
}
}
valueCopy.ensure(valueCopy.getBegin() + valueCopy.getRealSize() + carryLen);
s = valueCopy.getBegin() + carryP;
System.arraycopy(valueCopy.getUnsafeBytes(), s, valueCopy.getUnsafeBytes(), s + carryLen, valueCopy.getRealSize() - carryP);
System.arraycopy(carry, 0, valueCopy.getUnsafeBytes(), s, carryLen);
valueCopy.setRealSize(valueCopy.getRealSize() + carryLen);
return valueCopy;
}

public static NeighborChar succChar(Encoding enc, byte[] bytes, int p, int len) {
while (true) {
int i = len - 1;
for (; i >= 0 && bytes[p + i] == (byte)0xff; i--) bytes[p + i] = 0;
if (i < 0) return NeighborChar.WRAPPED;
bytes[p + i] = (byte)((bytes[p + i] & 0xff) + 1);
int cl = preciseLength(enc, bytes, p, p + len);
if (cl > 0) {
if (cl == len) {
return NeighborChar.FOUND;
} else {
for (int j = p + cl; j < p + len - cl; j++) bytes[j] = (byte)0xff;
}
}
if (cl == -1 && i < len - 1) {
int len2 = len - 1;
for (; len2 > 0; len2--) {
if (preciseLength(enc, bytes, p, p + len2) != -1) break;
}
for (int j = p + len2 + 1; j < p + len - (len2 + 1); j++) bytes[j] = (byte)0xff;
}
}
}

private static NeighborChar succAlnumChar(Encoding enc, byte[]bytes, int p, int len, byte[]carry, int carryP) {
byte save[] = new byte[org.jcodings.Config.ENC_CODE_TO_MBC_MAXLEN];
int c = enc.mbcToCode(bytes, p, p + len);

final int cType;
if (enc.isDigit(c)) {
cType = CharacterType.DIGIT;
} else if (enc.isAlpha(c)) {
cType = CharacterType.ALPHA;
} else {
return NeighborChar.NOT_CHAR;
}

System.arraycopy(bytes, p, save, 0, len);
NeighborChar ret = succChar(enc, bytes, p, len);
if (ret == NeighborChar.FOUND) {
c = enc.mbcToCode(bytes, p, p + len);
if (enc.isCodeCType(c, cType)) return NeighborChar.FOUND;
}

System.arraycopy(save, 0, bytes, p, len);
int range = 1;

while (true) {
System.arraycopy(bytes, p, save, 0, len);
ret = predChar(enc, bytes, p, len);
if (ret == NeighborChar.FOUND) {
c = enc.mbcToCode(bytes, p, p + len);
if (!enc.isCodeCType(c, cType)) {
System.arraycopy(save, 0, bytes, p, len);
break;
}
} else {
System.arraycopy(save, 0, bytes, p, len);
break;
}
range++;
}

if (range == 1) return NeighborChar.NOT_CHAR;

if (cType != CharacterType.DIGIT) {
System.arraycopy(bytes, p, carry, carryP, len);
return NeighborChar.WRAPPED;
}

System.arraycopy(bytes, p, carry, carryP, len);
succChar(enc, carry, carryP, len);
return NeighborChar.WRAPPED;
}

private static NeighborChar predChar(Encoding enc, byte[]bytes, int p, int len) {
while (true) {
int i = len - 1;
for (; i >= 0 && bytes[p + i] == 0; i--) bytes[p + i] = (byte)0xff;
if (i < 0) return NeighborChar.WRAPPED;
bytes[p + i] = (byte)((bytes[p + i] & 0xff) - 1);
int cl = preciseLength(enc, bytes, p, p + len);
if (cl > 0) {
if (cl == len) {
return NeighborChar.FOUND;
} else {
for (int j = p + cl; j < p + len - cl; j++) bytes[j] = 0;
}
}
if (cl == -1 && i < len - 1) {
int len2 = len - 1;
for (; len2 > 0; len2--) {
if (preciseLength(enc, bytes, p, p + len2) != -1) break;
}
for (int j = p + len2 + 1; j < p + len - (len2 + 1); j++) bytes[j] = 0;
}
}
}

public static boolean isSingleByteOptimizable(CodeRangeable string, Encoding encoding) {
return string.getCodeRange() == CR_7BIT || encoding.maxLength() == 1;
}

public static int index(CodeRangeable sourceString, ByteList source, int sourceLen, CodeRangeable subString, ByteList other, int otherLen, int offset, Encoding enc) {
if (subString.scanForCodeRange() == CR_BROKEN) return -1;
if (offset < 0) {
offset += sourceLen;
if (offset < 0) return -1;
}

if (sourceLen - offset < otherLen) return -1;
byte[]bytes = source.getUnsafeBytes();
int p = source.getBegin();
int end = p + source.getRealSize();
if (offset != 0) {
offset = isSingleByteOptimizable(sourceString, enc) ? offset : offset(enc, bytes, p, end, offset);
p += offset;
}
if (otherLen == 0) return offset;

while (true) {
int pos = source.indexOf(other, p - source.getBegin());
if (pos < 0) return pos;
pos -= (p - source.getBegin());
int t = enc.rightAdjustCharHead(bytes, p, p + pos, end);
if (t == p + pos) return pos + offset;
if ((sourceLen -= t - p) <= 0) return -1;
offset += t - p;
p = t;
}
}
}
1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/delete_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
fails:File.delete returns 0 when called without arguments
fails:File.delete deletes a single file
fails:File.delete deletes multiple files
fails:File.delete raises a TypeError if not passed a String type
fails:File.delete raises an Errno::ENOENT when the given file doesn't exist
1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/symlink_tags.txt
Original file line number Diff line number Diff line change
@@ -6,4 +6,3 @@ fails:File.symlink raises an ArgumentError if not called with two arguments
fails:File.symlink raises a TypeError if not called with String types
fails:File.symlink? returns true if the file is a link
fails:File.symlink? accepts an object that has a #to_path method
fails:File.symlink? returns false if the file does not exist
1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/unlink_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
fails:File.unlink returns 0 when called without arguments
fails:File.unlink deletes a single file
fails:File.unlink deletes multiple files
fails:File.unlink raises a TypeError if not passed a String type
fails:File.unlink raises an Errno::ENOENT when the given file doesn't exist
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/string/include_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:String#include? with String returns true if self contains other_str
fails:String#include? with String ignores subclass differences
fails:String#include? with String tries to convert other to string using to_str
fails:String#include? with String raises a TypeError if other can't be converted to string
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/string/insert_tags.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
fails:String#insert with index, other inserts other before the character at the given index
fails:String#insert with index, other modifies self in place
fails:String#insert with index, other inserts after the given character on an negative count
fails:String#insert with index, other raises an IndexError if the index is beyond string
fails:String#insert with index, other converts index to an integer using to_int
fails:String#insert with index, other converts other to a string using to_str
fails:String#insert with index, other taints self if string to insert is tainted
fails:String#insert with index, other raises a TypeError if other can't be converted to string
fails:String#insert with index, other raises a RuntimeError if self is frozen
fails:String#insert with index, other inserts a character into a multibyte encoded string
fails:String#insert with index, other returns a String in the compatible encoding
fails:String#insert with index, other raises an Encoding::CompatibilityError if the encodings are incompatible
6 changes: 0 additions & 6 deletions spec/truffle/tags/core/string/rindex_tags.txt
Original file line number Diff line number Diff line change
@@ -3,12 +3,6 @@ fails:String#rindex with object doesn't try to convert obj to an integer via to_
fails:String#rindex with object tries to convert obj to a string via to_str
fails:String#rindex with String behaves the same as String#rindex(char) for one-character strings
fails:String#rindex with String behaves the same as String#rindex(?char) for one-character strings
fails:String#rindex with String returns the index of the last occurrence of the given substring
fails:String#rindex with String doesn't set $~
fails:String#rindex with String ignores string subclasses
fails:String#rindex with String starts the search at the given offset
fails:String#rindex with String starts the search at offset + self.length if offset is negative
fails:String#rindex with String returns nil if the substring isn't found
fails:String#rindex with String tries to convert start_offset to an integer via to_int
fails:String#rindex with String raises a TypeError when given offset is nil
fails:String#rindex with Regexp behaves the same as String#rindex(string) for escaped string regexps
8 changes: 0 additions & 8 deletions spec/truffle/tags/core/string/succ_tags.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
fails:String#succ returns an empty string for empty strings
fails:String#succ returns the successor by increasing the rightmost alphanumeric (digit => digit, letter => letter with same case)
fails:String#succ increases non-alphanumerics (via ascii rules) if there are no alphanumerics
fails:String#succ increases the next best alphanumeric (jumping over non-alphanumerics) if there is a carry
fails:String#succ increases the next best character if there is a carry for non-alphanumerics
fails:String#succ adds an additional character (just left to the last increased one) if there is a carry and no character left to increase
fails:String#succ returns subclass instances when called on a subclass
fails:String#succ taints the result if self is tainted
fails:String#succ! is equivalent to succ, but modifies self in place (still returns self)
fails:String#succ! raises a RuntimeError if self is frozen
1 change: 0 additions & 1 deletion spec/truffle/truffle.mspec
Original file line number Diff line number Diff line change
@@ -107,7 +107,6 @@ class MSpecScript
"^spec/ruby/core/string/index_spec.rb",
"^spec/ruby/core/string/match_spec.rb",
"^spec/ruby/core/string/modulo_spec.rb",
"^spec/ruby/core/string/rindex_spec.rb",
"^spec/ruby/core/thread/raise_spec.rb",
]

0 comments on commit b4c11c6

Please sign in to comment.