Forums

Some .methods syntactic sugar?

General discussion about Cobra. Releases and general news will also be posted here.
Feel free to ask questions or just say "Hello".

Some .methods syntactic sugar?

Postby terenced » Wed Feb 16, 2011 6:59 am

Is there any syntactic sugar in Cobra so I can call .methods on an object and it will return me a list of method names and properties? Ruby has this and I find it great for prototyping/debugging code.
terenced
 
Posts: 15
Location: Montreal, Quebec, Canada

Re: Some .methods syntactic sugar?

Postby Charles » Wed Feb 16, 2011 2:19 pm

Here is some code to get you started. You can adapt it to your needs. In my case, I was interested in the argument and return type information as well. A lot of the code you see here is to output the reflection information in a form that is much closer to Cobra syntax. Also, since I wasn't printing any state for the object, I put the extension method on Type.

Should this be finished up and included in the standard library?

Btw this doesn't pick up PrimitiveTypeMembers and StandardLibraryExtensionMethods.

"""
See also:
CobraWorkspace/Source/ObjectExplorer-WinForms.cobra

Command line tools:
cobra -doc foo.cobra
cobra -doc-lib:Foo
"""

use System.Reflection


extend Type

def printCobraReflection
print this
# to-do: constructors
_printMethods(true) # print shared first. note that properties cannot be shared.
_printProperties
_printMethods(false)
print

def _printProperties
props = .getProperties.toList.sorted(do(a as PropertyInfo, b as PropertyInfo)=a.name.compareTo(b.name))
for prop in props
if prop.name == 'Item' # to-do: technically should be checking for an attribute
print ' ', r'[]' stop # to-do: print arguments
else
print ' ', _cobraMemberNameFor(prop.name) stop
if prop.canRead, print ' get' stop
if prop.canWrite, print ' set' stop
print

def _printMethods(isStatic as bool)
indent = if(isStatic, ' ', ' ')
methods = .getMethods.toList.sorted(do(a as MethodInfo, b as MethodInfo)=a.name.compareTo(b.name))
first = true
for method in methods
if method.isStatic <> isStatic, continue
if first and isStatic, print ' shared'
first = false
print indent stop
print _cobraMemberNameFor(method.name) stop
if method.getParameters.length
print '(' stop
sep = ''
for param in method.getParameters
# to-do: out and ref on parameters
# to-do: vari on parameters
# to-do: IEnumerable<of T> --> T*
paramTypeName = _cobraTypeNameFor(param.parameterType.name)
print '[sep][param.name] as [paramTypeName]' stop
sep = ', '
print ')' stop
if method.returnType and method.returnType.name <> 'Void'
print ' as', _cobraTypeNameFor(method.returnType.name) stop
# if method.isStatic, print ' is shared' stop
print

def _cobraMemberNameFor(name as String) as String
return if(name[0]=='_', '', '.') + name[0].toLower.toString + name[1:]

def _cobraTypeNameFor(name as String) as String
# to-do: handle generics. probably need actual type for that and not the name
if name.startsWith('System.'), name = name['System.'.length:]
if name.endsWith(r'[]'), return _cobraTypeNameFor(name[:-2]) + r'[]'
branch name
on 'Boolean', return 'bool'
on 'Char', return 'char'
on 'Int32', return 'int'
return name


class Program

def main
Object().typeOf.printCobraReflection
'Foo'.typeOf.printCobraReflection
t = [1, 2]
t.typeOf.printCobraReflection


Output:
Code: Select all
System.Object
    shared
        .equals(objA as Object, objB as Object) as bool
        .referenceEquals(objA as Object, objB as Object) as bool
    .equals(obj as Object) as bool
    .getHashCode as int
    .getType as Type
    .toString as String

System.String
    shared
        .compare(strA as String, indexA as int, strB as String, indexB as int, length as int) as int
        .compare(strA as String, indexA as int, strB as String, indexB as int, length as int, ignoreCase as bool) as int
        .compare(strA as String, strB as String) as int
        .compare(strA as String, strB as String, ignoreCase as bool) as int
        .compare(strA as String, strB as String, ignoreCase as bool, culture as CultureInfo) as int
        .compare(strA as String, strB as String, culture as CultureInfo, options as CompareOptions) as int
        .compare(strA as String, indexA as int, strB as String, indexB as int, length as int, culture as CultureInfo, options as CompareOptions) as int
        .compare(strA as String, indexA as int, strB as String, indexB as int, length as int, comparisonType as StringComparison) as int
        .compare(strA as String, indexA as int, strB as String, indexB as int, length as int, ignoreCase as bool, culture as CultureInfo) as int
        .compare(strA as String, strB as String, comparisonType as StringComparison) as int
        .compareOrdinal(strA as String, strB as String) as int
        .compareOrdinal(strA as String, indexA as int, strB as String, indexB as int, length as int) as int
        .concat(str0 as String, str1 as String) as String
        .concat(str0 as String, str1 as String, str2 as String) as String
        .concat(arg0 as Object, arg1 as Object, arg2 as Object, arg3 as Object) as String
        .concat(arg0 as Object, arg1 as Object, arg2 as Object) as String
        .concat(arg0 as Object, arg1 as Object) as String
        .concat(arg0 as Object) as String
        .concat(values as String[]) as String
        .concat(str0 as String, str1 as String, str2 as String, str3 as String) as String
        .concat(args as Object[]) as String
        .copy(str as String) as String
        .equals(a as String, b as String, comparisonType as StringComparison) as bool
        .equals(a as String, b as String) as bool
        .format(format as String, arg0 as Object, arg1 as Object, arg2 as Object) as String
        .format(provider as IFormatProvider, format as String, args as Object[]) as String
        .format(format as String, arg0 as Object) as String
        .format(format as String, arg0 as Object, arg1 as Object) as String
        .format(format as String, args as Object[]) as String
        .intern(str as String) as String
        .isInterned(str as String) as String
        .isNullOrEmpty(value as String) as bool
        .join(separator as String, value as String[]) as String
        .join(separator as String, value as String[], startIndex as int, count as int) as String
        .op_Equality(a as String, b as String) as bool
        .op_Inequality(a as String, b as String) as bool
    .chars get
    .length get
    .clone as Object
    .compareTo(value as Object) as int
    .compareTo(strB as String) as int
    .contains(value as String) as bool
    .copyTo(sourceIndex as int, destination as char[], destinationIndex as int, count as int)
    .endsWith(value as String, comparisonType as StringComparison) as bool
    .endsWith(value as String, ignoreCase as bool, culture as CultureInfo) as bool
    .endsWith(value as String) as bool
    .equals(value as String) as bool
    .equals(value as String, comparisonType as StringComparison) as bool
    .equals(obj as Object) as bool
    .get_Chars(index as int) as char
    .get_Length as int
    .getEnumerator as CharEnumerator
    .getHashCode as int
    .getType as Type
    .getTypeCode as TypeCode
    .indexOf(value as char, startIndex as int, count as int) as int
    .indexOf(value as String) as int
    .indexOf(value as String, startIndex as int, count as int) as int
    .indexOf(value as String, startIndex as int) as int
    .indexOf(value as String, startIndex as int, comparisonType as StringComparison) as int
    .indexOf(value as String, comparisonType as StringComparison) as int
    .indexOf(value as String, startIndex as int, count as int, comparisonType as StringComparison) as int
    .indexOf(value as char, startIndex as int) as int
    .indexOf(value as char) as int
    .indexOfAny(anyOf as char[]) as int
    .indexOfAny(anyOf as char[], startIndex as int) as int
    .indexOfAny(anyOf as char[], startIndex as int, count as int) as int
    .insert(startIndex as int, value as String) as String
    .isNormalized(normalizationForm as NormalizationForm) as bool
    .isNormalized as bool
    .lastIndexOf(value as char, startIndex as int, count as int) as int
    .lastIndexOf(value as char, startIndex as int) as int
    .lastIndexOf(value as String, startIndex as int) as int
    .lastIndexOf(value as String) as int
    .lastIndexOf(value as String, startIndex as int, comparisonType as StringComparison) as int
    .lastIndexOf(value as String, comparisonType as StringComparison) as int
    .lastIndexOf(value as char) as int
    .lastIndexOf(value as String, startIndex as int, count as int, comparisonType as StringComparison) as int
    .lastIndexOf(value as String, startIndex as int, count as int) as int
    .lastIndexOfAny(anyOf as char[], startIndex as int, count as int) as int
    .lastIndexOfAny(anyOf as char[], startIndex as int) as int
    .lastIndexOfAny(anyOf as char[]) as int
    .normalize as String
    .normalize(normalizationForm as NormalizationForm) as String
    .padLeft(totalWidth as int, paddingChar as char) as String
    .padLeft(totalWidth as int) as String
    .padRight(totalWidth as int) as String
    .padRight(totalWidth as int, paddingChar as char) as String
    .remove(startIndex as int, count as int) as String
    .remove(startIndex as int) as String
    .replace(oldValue as String, newValue as String) as String
    .replace(oldChar as char, newChar as char) as String
    .split(separator as char[], count as int, options as StringSplitOptions) as String[]
    .split(separator as char[], count as int) as String[]
    .split(separator as char[]) as String[]
    .split(separator as String[], options as StringSplitOptions) as String[]
    .split(separator as char[], options as StringSplitOptions) as String[]
    .split(separator as String[], count as int, options as StringSplitOptions) as String[]
    .startsWith(value as String) as bool
    .startsWith(value as String, ignoreCase as bool, culture as CultureInfo) as bool
    .startsWith(value as String, comparisonType as StringComparison) as bool
    .substring(startIndex as int) as String
    .substring(startIndex as int, length as int) as String
    .toCharArray(startIndex as int, length as int) as char[]
    .toCharArray as char[]
    .toLower as String
    .toLower(culture as CultureInfo) as String
    .toLowerInvariant as String
    .toString as String
    .toString(provider as IFormatProvider) as String
    .toUpper as String
    .toUpper(culture as CultureInfo) as String
    .toUpperInvariant as String
    .trim(trimChars as char[]) as String
    .trim as String
    .trimEnd(trimChars as char[]) as String
    .trimStart(trimChars as char[]) as String

System.Collections.Generic.List`1[System.Int32]
    .capacity get set
    .count get
    [] get set
    .add(item as int)
    .addRange(collection as IEnumerable`1)
    .asReadOnly as ReadOnlyCollection`1
    .binarySearch(index as int, count as int, item as int, comparer as IComparer`1) as int
    .binarySearch(item as int, comparer as IComparer`1) as int
    .binarySearch(item as int) as int
    .clear
    .contains(item as int) as bool
    .convertAll(converter as Converter`2) as List`1
    .copyTo(index as int, array as int[], arrayIndex as int, count as int)
    .copyTo(array as int[], arrayIndex as int)
    .copyTo(array as int[])
    .equals(obj as Object) as bool
    .exists(match as Predicate`1) as bool
    .find(match as Predicate`1) as int
    .findAll(match as Predicate`1) as List`1
    .findIndex(startIndex as int, count as int, match as Predicate`1) as int
    .findIndex(match as Predicate`1) as int
    .findIndex(startIndex as int, match as Predicate`1) as int
    .findLast(match as Predicate`1) as int
    .findLastIndex(startIndex as int, count as int, match as Predicate`1) as int
    .findLastIndex(match as Predicate`1) as int
    .findLastIndex(startIndex as int, match as Predicate`1) as int
    .forEach(action as Action`1)
    .get_Capacity as int
    .get_Count as int
    .get_Item(index as int) as int
    .getEnumerator as Enumerator
    .getHashCode as int
    .getRange(index as int, count as int) as List`1
    .getType as Type
    .indexOf(item as int) as int
    .indexOf(item as int, index as int) as int
    .indexOf(item as int, index as int, count as int) as int
    .insert(index as int, item as int)
    .insertRange(index as int, collection as IEnumerable`1)
    .lastIndexOf(item as int, index as int) as int
    .lastIndexOf(item as int, index as int, count as int) as int
    .lastIndexOf(item as int) as int
    .remove(item as int) as bool
    .removeAll(match as Predicate`1) as int
    .removeAt(index as int)
    .removeRange(index as int, count as int)
    .reverse
    .reverse(index as int, count as int)
    .set_Capacity(value as int)
    .set_Item(index as int, value as int)
    .sort(comparison as Comparison`1)
    .sort(comparer as IComparer`1)
    .sort
    .sort(index as int, count as int, comparer as IComparer`1)
    .toArray as int[]
    .toString as String
    .trimExcess
    .trueForAll(match as Predicate`1) as bool
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Some .methods syntactic sugar?

Postby terenced » Thu Feb 17, 2011 9:03 am

Perfect!!!
I would like to see a version of this included in the standard library
terenced
 
Posts: 15
Location: Montreal, Quebec, Canada

Re: Some .methods syntactic sugar?

Postby hopscc » Fri Feb 18, 2011 5:07 am

Is it useful in the stdLib?
Youd hardly use it much in developing a normal program and you'd have to write a program around it to probe any class you were interested in,

Wouldnt it be better off as an adjunct utility/tool.
Gui or cmdline program that you provided the Type name (and maybe the containing assembly/ref) you wanted to know about and it ran against that dumping the info ....
hopscc
 
Posts: 632
Location: New Plymouth, Taranaki, New Zealand

Re: Some .methods syntactic sugar?

Postby terenced » Fri Feb 18, 2011 5:53 am

Well, in my case, I was prototype some code, and I wasn't sure the type or it methods (I was messing about with System.Xml.Linq). I can do a
print x.getType
and the look it up online or in a tool. However, wouldn't it be much quicker to get it all in one shot
print x.methods

However, I say this now, but if Cobra had better IDE support, then maybe I wouldn't care about it. :D
terenced
 
Posts: 15
Location: Montreal, Quebec, Canada

Re: Some .methods syntactic sugar?

Postby hopscc » Sat Feb 19, 2011 4:37 am

Sure but we dont have a interactive interpreter for cobra (yet :) )so you have to put the
Code: Select all
x = SomeType()
print x.methods

in a file, compile and run the generated exe - a coupla extra steps... (even with editor/IDE compile and run support)

A separate tool (cobratypeshow say) would just allow something like (cmdline)
Code: Select all
$ cobratypeshow SomeType
hopscc
 
Posts: 632
Location: New Plymouth, Taranaki, New Zealand

Re: Some .methods syntactic sugar?

Postby terenced » Sat Feb 19, 2011 5:07 am

Agreed, whoever, I was playing about with Linq at the time, and was sure what the type was.
I just wish we had IDE support :(
terenced
 
Posts: 15
Location: Montreal, Quebec, Canada

Re: Some .methods syntactic sugar?

Postby torial » Sat Feb 19, 2011 11:47 am

So what would your IDE requirements be? Are you looking for a forms designer? I know that RIGHT_THEN has recently updated the Cobra SharpDevelop plugin. It isn't feature complete, but might be a good starting point.
torial
 
Posts: 229
Location: IA

Re: Some .methods syntactic sugar?

Postby Charles » Sat Feb 19, 2011 3:26 pm

In addition to SharpDevelop, there is Visual Studio support although we haven't gotten anywhere on Intellisense AFAIK. In general, there is an IDE Support wiki page. For anybody working on IDE support, please update your respective wiki page as needed to show the current status, download URL, etc. The IDE Support wiki page is linked from the Downloads page.

Regarding a tool for dumping a type's interface:

-- We have a "cobra -doc-lib:Foo" command for which I was intending to allow you to add a type onto it. Plus it probably needs some fixing and polish. Plus I just noticed that it's not listed in the help anywhere.

-- If we want something a little more convenient where Cobra tries to infer the DLL then I'm picturing "cobra show-type Foo.Bar" when subcommands arrive. I'm part way through implementing subcommands btw.

-- It's still the case that I have often wanted to be able to stick a "obj.typeOf.printCobraReflection" in my existing programs where I already have the "obj", but may not know the type and/or am feel lazing about jumping out of my edit-run cycle to look stuff up.

-- It would be nice if such libs could be optionally included only when used. But I haven't formulated exactly how that would work.
Charles
 
Posts: 2515
Location: Los Angeles, CA


Return to Discussion

Who is online

Users browsing this forum: No registered users and 3 guests