Skip to content

Instantly share code, notes, and snippets.

@peteroupc
Last active May 28, 2021 22:23
Show Gist options
  • Save peteroupc/16b7c01e9333d03ca833 to your computer and use it in GitHub Desktop.
Save peteroupc/16b7c01e9333d03ca833 to your computer and use it in GitHub Desktop.
Replaces pseudo method calls in C# or Java source code with argument check code.
#!/usr/bin/ruby
=begin
Written by Peter O.
Any copyright to this work is released to the Public Domain.
In case this is not possible, this work is also
licensed under Creative Commons Zero (CC0):
https://creativecommons.org/publicdomain/zero/1.0/
Replaces pseudo method calls in C# or Java
source code with argument check code.
The following method calls are supported.
ArgumentAssert.CheckIndex(array, index);
Fails if the index is out of bounds.
ArgumentAssert.CheckBuffer(array, index, length);
Fails if the portion of the array is out of bounds.
ArgumentAssert.CheckListBuffer(array, index, length);
Fails if the portion of the array list is out of bounds.
ArgumentAssert.CheckStringBuffer(array, index, length);
Fails if the portion of the string is out of bounds.
ArgumentAssert.CheckStringBufferIndexes(array, index, endIndex);
Fails if the portion of the string with the given index
and up to but not including the end index is out of bounds.
ArgumentAssert.CheckRange(number, minValue, maxValue);
Fails if the number is not in range.
ArgumentAssert.Greater(number, minValue);
ArgumentAssert.GreaterOrEqual(number, minValue);
ArgumentAssert.Less(number, maxValue);
ArgumentAssert.NotNegative(number);
ArgumentAssert.LessOrEqual(number, maxValue);
ArgumentAssert.NotNull(value);
ArgumentAssert.NotEmpty(value);
Fails if the string is null or an empty string.
ArgumentAssert.IsTrue(condition);
ArgumentAssert.AreEqual(object1, object2);
Fails if the objects are not equal under the Equals method.
ArgumentAssert.AreNotEqual(object1, object2);
Fails if the objects are equal under the Equals method.
ArgumentAssert.AreSame(object1, object2);
Fails if the objects' references are not the same.
In each example above, ArgumentAssert can be replaced with DebugAssert,
except that the code is converted to a Java assert or enabled only
in C# debug mode.
=end
def cleanAsserts(x,csharp) # (source code, csharp/java flag)
getParenParam=proc{
parenend="[^\\,\\(\\)]*"
parenmiddle="[^\\(\\)]*"
parentwolevelextra="(?:\\(#{parenmiddle}(?:\\(#{parenmiddle}\\)#{parenmiddle})*\\)#{parenend})*"
parentwolevel="\\(#{parenmiddle}(?:\\(#{parenmiddle}\\)#{parenmiddle})*\\)#{parenend}"+parentwolevelextra
parenparam="(#{parenend}|#{parenend}#{parentwolevel})"
next parenparam
}
x=x.clone
parenparam=getParenParam.call()
npe=(csharp) ? "ArgumentNullException" : "NullPointerException"
iae=(csharp) ? "ArgumentException" : "IllegalArgumentException"
ioobe=(csharp) ? "ArgumentException" : "IndexOutOfBoundsException"
equals=(csharp) ? "Equals" : "equals"
stringlen=(csharp) ? "Length" : "length()"
listlen=(csharp) ? "Count" : "size()"
arraylen=(csharp) ? "Length" : "length"
tolong=proc{|o|
ret="#{o}"
ret="(#{o})" if ret.include?("-")
next ret
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckIndex\s*\(#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.CheckIndex(#{m[3]},#{m[4]},#{m[3].inspect},#{m[4].inspect})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckIndex\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.NotNull(#{m[3]},#{m[5]});\n"+
"#{m[1]}#{m[2]}.GreaterOrEqual(#{m[4]},0,#{m[6]});\n"+
"#{m[1]}#{m[2]}.LessOrEqual(#{m[4]},#{m[3]}.#{arraylen},#{m[6]})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckBuffer\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.CheckBuffer(#{m[3]},#{m[4]},#{m[5]},#{m[3].inspect},#{m[4].inspect},#{m[5].inspect})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckListBuffer\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.CheckListBuffer(#{m[3]},#{m[4]},#{m[5]},#{m[3].inspect},#{m[4].inspect},#{m[5].inspect})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckBuffer\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6,$7]
"#{m[1]}#{m[2]}.NotNull(#{m[3]},#{m[6]});\n"+
(m[4]=="0" ? "" : "#{m[1]}#{m[2]}.CheckRange(#{m[4]},0,#{m[3]}.#{arraylen},#{m[7]});\n")+
"#{m[1]}#{m[2]}.CheckRange(#{m[5]},0,#{m[3]}.#{arraylen},#{m[8]});\n"+
(m[4]=="0" ?
"#{m[1]}#{m[2]}.GreaterOrEqual((#{m[3]}.#{arraylen}),#{m[5]},#{m[3].inspect} + \"'s length\")" :
"#{m[1]}#{m[2]}.GreaterOrEqual((#{m[3]}.#{arraylen}-#{m[4]}),#{m[5]},#{m[3].inspect} + \"'s length minus \" + #{m[4]})")
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckListBuffer\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.NotNull(#{m[3]},#{m[6]});\n"+
(m[4]=="0" ? "" : "#{m[1]}#{m[2]}.CheckRange(#{m[4]},0,#{m[3]}.#{listlen},#{m[7]});\n")+
"#{m[1]}#{m[2]}.CheckRange(#{m[5]},0,#{m[3]}.#{listlen},#{m[8]});\n"+
(m[4]=="0" ?
"#{m[1]}#{m[2]}.GreaterOrEqual((#{m[3]}.#{listlen}),#{m[5]},#{m[3].inspect} + \"'s length\")" :
"#{m[1]}#{m[2]}.GreaterOrEqual((#{m[3]}.#{listlen}-#{m[4]}),#{m[5]},#{m[3].inspect} + \"'s length minus \" + #{m[4]})")
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckStringBuffer\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.CheckStringBuffer(#{m[3]},#{m[4]},#{m[5]},#{m[3].inspect},#{m[4].inspect},#{m[5].inspect})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckStringBuffer\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6,$7]
"#{m[1]}#{m[2]}.NotNull(#{m[3]},#{m[6]});\n"+
(m[4]=="0" ? "" : "#{m[1]}#{m[2]}.CheckRange(#{m[4]},0,#{m[3]}.#{stringlen},#{m[7]});\n")+
"#{m[1]}#{m[2]}.CheckRange(#{m[5]},0,#{m[3]}.#{stringlen},#{m[8]});\n"+
(m[4]=="0" ?
"#{m[1]}#{m[2]}.GreaterOrEqual((#{m[3]}.#{stringlen}),#{m[5]},#{m[3].inspect} + \"'s length\")" :
"#{m[1]}#{m[2]}.GreaterOrEqual((#{m[3]}.#{stringlen}-#{m[4]}),#{m[5]},#{m[3].inspect} + \"'s length minus \" + #{m[4]})")
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckStringBufferIndexes\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.CheckStringBufferIndexes(#{m[3]},#{m[4]},#{m[5]},#{m[3].inspect},#{m[4].inspect},#{m[5].inspect})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckStringBufferIndexes\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6,$7]
"#{m[1]}#{m[2]}.NotNull(#{m[3]},#{m[6]});\n"+
"#{m[1]}#{m[2]}.CheckRange(#{m[4]},0,#{m[3]}.#{stringlen},#{m[7]});\n"+
"#{m[1]}#{m[2]}.CheckRange(#{m[5]},0,#{m[3]}.#{stringlen},#{m[8]});\n"+
"#{m[1]}#{m[2]}.GreaterOrEqual(#{m[5]},#{m[4]},#{m[8]})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckRange\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.GreaterOrEqual(#{m[3]},#{m[4]},#{m[3].inspect});\n"+
"#{m[1]}#{m[2]}.LessOrEqual(#{m[3]},#{m[5]},#{m[3].inspect})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckRange\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.GreaterOrEqual(#{m[3]},#{m[4]},#{m[6]});\n"+
"#{m[1]}#{m[2]}.LessOrEqual(#{m[3]},#{m[5]},#{m[6]})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.CheckBuffer\s*\(#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.NotNull(#{m[3]},#{m[3].inspect});\n"+
"#{m[1]}#{m[2]}.GreaterOrEqual(#{m[4]},0,#{m[4].inspect});\n"+
"#{m[1]}#{m[2]}.LessOrEqual(#{m[4]} + 1,#{m[3]}.#{arraylen},#{m[4].inspect} + \" plus 1\")"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.(Greater|Less|GreaterOrEqual|LessOrEqual|AreEqual|AreNotEqual)\s*\(#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.#{m[3]}(#{m[4]},#{m[5]},#{m[4].inspect})"
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.(NotNull|NotEmpty|NotNegative)\s*\(#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
if m[3]=="NotNull" && csharp
next "#{m[1]}#{m[2]}.#{m[3]}(#{m[4]},nameof(#{m[4]}))"
else
next "#{m[1]}#{m[2]}.#{m[3]}(#{m[4]},#{m[4].inspect})"
end
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.NotNegative\s*\(#{parenparam},\s*#{parenparam}\)/){
m=[nil,$1,$2,$3,$4,$5,$6]
"#{m[1]}#{m[2]}.GreaterOrEqual(#{m[3]},0,#{m[4]})"
}
# Basic methods
assertproc=proc{|indent,cond,exceptname,message,debug,csharp|
if csharp
if debug
next "#if DEBUG\n#{indent}if (#{cond}) {\n#{indent} throw new #{exceptname}(#{message});\n#{indent}}\n#endif\n"
else
next "#{indent}if (#{cond}) {\n#{indent} throw new #{exceptname}(#{message});\n#{indent}}"
end
else
if debug
next "assert (!(#{cond})) : (#{message});"
else
next "#{indent}if (#{cond}) {\n#{indent} throw new #{exceptname}(#{message});\n#{indent}}"
end
end
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.NotEmpty\s*\(#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
debug=(m[2]=="DebugAssert")
next "#{m[1]}#{m[2]}.NotNull(#{m[3]},#{m[4]});\n"+
assertproc.call(m[1],"("+m[3]+").#{stringlen}==0",iae,"#{m[4]}+ \" is empty.\"",debug,csharp)
}
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.IsTrue\s*\(#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"!("+m[3]+")",iae,"#{m[4]}",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.NotNull\s*\(#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"("+m[3]+") == null",npe,"#{m[4]}",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.IsTrue\s*\(#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"!("+m[3]+")",iae,"#{('doesn\'t satisfy '+m[3].to_s).inspect}",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.Less\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"(#{m[3]}) >= #{m[4]}",ioobe,(m[5]||"").inspect+" + \" (\" + #{tolong.call(m[3])} + \") is not less than \" + #{tolong.call(m[4])}",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.Greater\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"(#{m[3]}) <= #{m[4]}",ioobe,(m[5]||"").inspect+" + \" (\" + #{tolong.call(m[3])} + \") is not greater than \" + #{tolong.call(m[4])}",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.LessOrEqual\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"(#{m[3]}) > #{m[4]}",ioobe,(m[5]||"").inspect+" + \" (\" + #{tolong.call(m[3])} + \") is not less or equal to \" + #{tolong.call(m[4])}",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.GreaterOrEqual\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"(#{m[3]}) < #{m[4]}",ioobe,(m[5]||"").inspect+" + \" (\" + #{tolong.call(m[3])} + \") is not greater or equal to \" + #{tolong.call(m[4])}",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.AreEqual\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"!(#{m[3]}).#{equals}(#{m[4]})",ioobe,(m[5]||"").inspect+" + \" (\" + (#{m[3]}) + \") is not equal to \" + (#{m[4]})",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.AreNotEqual\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"(#{m[3]}).#{equals}(#{m[4]})",ioobe,(m[5]||"").inspect+" + \" (\" + (#{m[3]}) + \") is not equal to \" + (#{m[4]})",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.AreSame\s*\(#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"(#{m[3]}) != (#{m[4]})",ioobe,"#{m[3].inspect} + \" (\" + #{m[3]} + \") is not equal to \" + (#{m[4]})",m[2]=="DebugAssert",csharp) }
x.gsub!(/([ \t]*)(ArgumentAssert|DebugAssert)\.AreSame\s*\(#{parenparam},\s*#{parenparam},\s*#{parenparam}\)\s*;/){
m=[nil,$1,$2,$3,$4,$5,$6]
assertproc.call(m[1],"(#{m[3]}) != (#{m[4]})",ioobe,(m[5]||"").inspect+" + \" (\" + (#{m[3]}) + \") is not equal to \" + (#{m[4]})",m[2]=="DebugAssert",csharp) }
x.gsub!(/\#endif\s*\#if\s+DEBUG\b([ \t]*\r?\n)?/,"")
x.gsub!(/\"\s*\+\s*\" \(/," (")
x.gsub!(/\"\s*\+\s*\" not greater/," not greater")
x.gsub!(/\"\s*\+\s*\"\'s length/,"'s length")
x.gsub!(/\"\s*\+\s*\" not less/," not less")
return x
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment