In the spoon code analysis tool, the AST is visualized in a GUI using the command:
$ java -cp spoon-core-5.9.0-jar-with-dependencies.jar spoon.Launcher -i MyClass.java --gui --noclasspath
I am trying to run the same command without the -gui but, I dont get any output. Is there anyway i can get the AST in a text file.
Use Spoon processors. Any Spoon processor will visit all the elements of the AST in pre-order, so you could simply create a CtElement processor and print the element being visited:
#Override
public void process(CtElement element) {
//Find the level in the Syntax Tree of the element
int n = 0;
CtElement parent = element.getParent();
while (parent != null) {
n++;
parent = parent.getParent();
}
// Print the element
try {
String s = "";
if (n > 0) s = String.format("%0" + n + "d", 0).replace("0","-");
System.out.println(s + element.getClass().getSimpleName());
} catch (NullPointerException ex) {
System.out.println("Unknown Element");
}
}
You can use the JavaFX app called showMeYourSpoon dedicated for visualising the Spoon AST of some Java code.
This tool, however, cannot take as input all the sources of a project (at max one class, for example your class MyClass.java).
https://github.com/inspectorguidget/showMeYourSpoon
Using the application you can write or copy-paste your Java code in the dedicated text area and the corresponding Spoon AST will then be computed and displayed.
To export the Spoon AST in a text file, you can click on the save button.
This application has other features such as:
showing/masking implicit elements of the AST
clicking on a Java code element automatically selects the corresponding AST element in the tree view
clicking on an AST element in the tree view selects the corresponding Java code chunk in the text area
specifying the kind of Java code you write (a class, a class element, a statement, or an expression)
Screenshot of showMeYourSpoon
Related
I am recursively traversing an antlr parse tree and I want to edit the text of TerminalNodes in the tree. I want to be able to do this for any ParseTree and I don't want to write a specific Visitor for each ParseTree I may encounter.
I have looked through The Definitive ANTLR4 Reference and seen that antlr doesn't have any direct support for tree rewriting. I am looking for any possible workarounds or alternative solutions.
private void editTree(ParseTree tree){
for(int i = 0; i < tree.getChildCount();i++){
ParseTree child = tree.getChild(i);
if(child instanceof TerminalNode){
//Edit child's text
} else {
editTree(child);
}
}
}
TerminalNode has a member getSymbol(), which returns the lexed token. This is usually a CommonToken instance, which allows to set the text and other properties like line number, type etc. ParseTree.getText() does nothing else but asking the symbol to provide the text (which in turn is what you can set or what comes from the input stream).
I'm creating a Doubly Linked List from a Binary Search Tree using recursion and it works perfectly fine when the BST is already populated, i.e. >=2 nodes.
However, I tried running it for a BST that is dynamically getting populated and it gives me a StackOverFlowError as soon as I insert a child to the root node in the BST.
Here is the code (in Java) I've written
public class BSTtoDLL {
/* Binary Search Tree to Doubly Linked List conversion*/
// head --> Pointer to head node of created doubly linked list
static BTNode head;
// Initialize previously visited node as NULL. This is
// static so that the same value is accessible in all recursive
// calls
static BTNode prev = null;
/* BSTtoDLL Construtor */
public BSTtoDLL(){
head = null;
prev = null;
}
// A simple recursive function to convert a given Binary tree
// to Doubly Linked List
// root --> Root of Binary Tree
void BinaryTree2DoubleLinkedList(BTNode root)
{
// Base case
if (root == null)
return;
// Recursively convert left subtree
if(root.left!=null)
BinaryTree2DoubleLinkedList(root.left);
// Now convert this node
if (prev == null){
head = root;
}
else
{
prev.right = root;
root.left = prev;
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.right);
}
And the the console response:
Binary Tree Test
Converting to a DLL
Data--34--Left is Null----Right
is Null--- Binary Tree Test Converting to a DLL Exception in thread
"main" java.lang.StackOverflowError at
com.techwealth.BSTtoDLL.BinaryTree2DoubleLinkedList(BSTtoDLL.java:32)
at
com.techwealth.BSTtoDLL.BinaryTree2DoubleLinkedList(BSTtoDLL.java:32)
at
com.techwealth.BSTtoDLL.BinaryTree2DoubleLinkedList(BSTtoDLL.java:32)
at
com.techwealth.BSTtoDLL.BinaryTree2DoubleLinkedList(BSTtoDLL.java:32)
at
com.techwealth.BSTtoDLL.BinaryTree2DoubleLinkedList(BSTtoDLL.java:32)
Clearly, you are missing the termination condition(the base case is invalidated as you are using static variables). That is the reason why you are seeing stackoverflow error. Go through this link for more info regarding this error: What is a StackOverflowError?
Since getting started in Dart I've been watching for a way to execute Dart (Text) Source (that the same program may well be generating dynamically) as Code. Like the infamous "eval()" function.
Recently I have caught a few hints that the communication port between Isolates support some sort of "Spawn" that seems like it could allow this "trick". In Ruby there is also the possibility to load a module dynamically as a language feature, perhaps there is some way to do this in Dart?
Any clues or a simple example will be greatly appreciated.
Thanks in advance!
Ladislav Thon provided this answer on the Dart forum:
I believe it's very safe to say that Dart will never have eval. But it will have other, more structured ways of dynamically generating code (code name mirror builders). There is nothing like that right now, though.
There are two ways of spawning an isolate: spawnFunction, which runs an existing function from the existing code in a new isolate, so nothing you are looking for, and spawnUri, which downloads code from given URI and runs it in new isolate. That is essentially dynamic code loading -- but the dynamically loaded code is isolated from the existing code. It runs in a new isolate, so the only means of communicating with it is via message passing (through ports).
You can run a string as Dart code by first constructing a data URI from it and then passing it into Isolate.spawnUri.
import 'dart:isolate';
void main() async {
final uri = Uri.dataFromString(
'''
void main() {
print("Hellooooooo from the other side!");
}
''',
mimeType: 'application/dart',
);
await Isolate.spawnUri(uri, [], null);
}
Note that you can only do this in JIT mode, which means that the only place you might benefit from it is Dart VM command line apps / package:build scripts. It will not work in Flutter release builds.
To get a result back from it, you can use ports:
import 'dart:isolate';
void main() async {
final name = 'Eval Knievel';
final uri = Uri.dataFromString(
'''
import "dart:isolate";
void main(_, SendPort port) {
port.send("Nice to meet you, $name!");
}
''',
mimeType: 'application/dart',
);
final port = ReceivePort();
await Isolate.spawnUri(uri, [], port.sendPort);
final String response = await port.first;
print(response);
}
I wrote about it on my blog.
Eval(), in Ruby at least, can execute anything from a single statement (like an assignment) to complete involved programs. There is a substantial time penalty for executing many small snippets over most any other form of execution that is possible.
Looking at the problem closer, there are at least three different functions that were at the base of the various schemes where eval might be used. Dart handles at least 2 of these in at least minimal ways.
Dart does not, nor does it look like there is any plan to support "general" script execution.
However, the NoSuchMethod method can be used to effectively implement the dynamic "injection" of variables into your local class environment. It replaces an eval() with a string that would look like this: eval( "String text = 'your first name here';" );
The second function that Dart readily supports now is the invocation of a method, that would look like this: eval( "Map map = SomeClass.some_method()" );
After messing about with this it finally dawned on me that a single simple class can be used to store the information needed to invoke a method, for a class, as a string which seems to have general utility. I can replace a big maintenance prone switch statement that might otherwise be necessary to invoke a series of methods. In Ruby this was almost trivial, however in Dart there are some fairly less than intuitive calls so I wanted to get this "trick" in one place, which fits will with doing ordering and filtering on the strings such as you may need.
Here's the code to "accumulate" as many classes (a whole library?) into a map using reflection such that the class.methodName() can be called with nothing more than a key (as a string).
Note: I used a few "helper methods" to do Map & List functions, you will probably want to replace them with straight Dart. However this code is used and tested only using the functions..
Here's the code:
//The used "Helpers" here..
MAP_add(var map, var key, var value){ if(key != null){map[key] = value;}return(map);}
Object MAP_fetch(var map, var key, [var dflt = null]) {var value = map[key];if (value==null) {value = dflt;}return( value );}
class ClassMethodMapper {
Map _helperMirrorsMap, _methodMap;
void accum_class_map(Object myClass){
InstanceMirror helperMirror = reflect(myClass);
List methodsAr = helperMirror.type.methods.values;
String classNm = myClass.toString().split("'")[1]; ///#FRAGILE
MAP_add(_helperMirrorsMap, classNm, helperMirror);
methodsAr.forEach(( method) {
String key = method.simpleName;
if (key.charCodeAt(0) != 95) { //Ignore private methods
MAP_add(_methodMap, "${classNm}.${key}()", method);
}
});
}
Map invoker( String methodNm ) {
var method = MAP_fetch(_methodMap, methodNm, null);
if (method != null) {
String classNm = methodNm.split('.')[0];
InstanceMirror helperMirror = MAP_fetch(_helperMirrorsMap, classNm);
helperMirror.invoke(method.simpleName, []);
}
}
ClassMethodMapper() {
_methodMap = {};
_helperMirrorsMap = {};
}
}//END_OF_CLASS( ClassMethodMapper );
============
main() {
ClassMethodMapper cMM = new ClassMethodMapper();
cMM.accum_class_map(MyFirstExampleClass);
cMM.accum_class_map(MySecondExampleClass);
//Now you're ready to execute any method (not private as per a special line of code above)
//by simply doing this:
cMM.invoker( MyFirstExampleClass.my_example_method() );
}
Actually there some libraries in pub.dev/packages but has some limitations because are young versions, so that I can recommend you this library expressions to dart and flutter.
A library to parse and evaluate simple expressions.
This library can handle simple expressions, but no blocks of code, control flow statements and so on. It supports a syntax that is common to most programming languages.
There I create an example of code to evaluate arithmetic operations and comparations of data.
import 'package:expressions/expressions.dart';
import 'dart:math';
#override
Widget build(BuildContext context) {
final parsing = FormulaMath();
// Expression example
String condition = "(cos(x)*cos(x)+sin(x)*sin(x)==1) && respuesta_texto == 'si'";
Expression expression = Expression.parse(condition);
var context = {
"x": pi / 5,
"cos": cos,
"sin": sin,
"respuesta_texto" : 'si'
};
// Evaluate expression
final evaluator = const ExpressionEvaluator();
var r = evaluator.eval(expression, context);
print(r);
return Scaffold(
body: Container(
margin: EdgeInsets.only(top: 50.0),
child: Column(
children: [
Text(condition),
Text(r.toString())
],
),
),
);
}
I/flutter (27188): true
How are you finding out if jqGrid is loaded and ready to be used, via selenium.
Some details :
Im using C# driver
I have a method : new WebDriverWait(driver, new TimeSpan(0, 0, 0, 30)).Until(x => loadingdissapearedcondition) which im using to wait until Loading.. element is gone.
I also sometimes use this script :
private const string script = #"return ($('#{0}').jqGrid('getGridParam', 'reccount') !=x undefined) && ($('#{0}').jqGrid('getGridParam', 'reccount') != 0) && (!$('#load_{0}').is(':visible')) && (!$('#busyIcon').is(':visible'))";
private readonly string waitScript;
waitScript = string.Format(script, jqGridId);
public void WaitUntilLoadIconDissappears()
{
driver.WaitUntil(MAXWAIT, Wait);
}
public bool Wait()
{
var executeScript = ((IJavaScriptExecutor) driver).ExecuteScript(waitScript);
bool result;
bool tryParse = bool.TryParse(executeScript.SafeToString(), out result);
return tryParse && result;
}
to find if jqGrid has records and loading done.
I require something better - as even the above two does not make driver wait until load finishes, if we are using local data for jqGrid. Im also curious what is the best way, or at the minimum, how others are dealing with this problem.
I never used Selenium before, so I'm not sure that I understood your problem correctly. jqGrid will be first initialized and then (optionally) the data can be loaded from the server. During the initializing stage the original <table id="grid"></table> element will be converted to relatively complex HTML fragment which is the grid. At the end of the initialization the DOM element of the table (the $("#grid")[0]) will get the expando grid.
So you can use the test like
if ($("#grid")[0].grid) {
// grid is initialized
}
to determine that the grid is already initialized. jqGrid uses the same test internally (see here for example).
Here is solution for Java and jqgrid.
If grid data is not loaded yet then right pager has no value, so simply check its length. Methods such as isElementPresent, isDisplayed etc. seems not to work for grid right pager object. It's always present in page code while ajax, but text value is set when dynamic data is loaded.
public void waitForGridPagerRight(String gridName) throws Exception {
for (int second = 0;; second++) {
if (second >= 15) {
fail("Timeout.");
}
try {
if (driver
.findElement(By.id("pager_" + gridName + "_right"))
.getText().length() > 2)
break;
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
Not sure why #Oleg's answer didn't work for me. It seemed like grid was being populated even before the ajax call was being made. It appears there's some change in newer versions maybe. It look like the last thing to happen in the ajax call is that the "loading" block is hidden, so instead I find that element and check it's display attribute a la:
def wait_for_jqgrid(self, t=20):
def check_jqgrid(driver):
#the last thing jqgrid does after the ajax call is to turn off the loading div
#so we find it and check to see if its display attribute is no longer set to 'none'
script = 'pid = $.jgrid.jqID($(".ui-jqgrid-btable").get(0).p.id); return $("#load_"+pid).get(0).style.display == "none";'
return driver.execute_script(script)
WebDriverWait(self.driver, t).until(check_jqgrid)
When the loading div is hidden, we are done. This is python but the same javascript bit should work in Java or whatever.
I've got a bunch of test scripts written using Test::WWW::Selenium (but the fact that I used perl is inconsequential, any language selenium supports probably has the problem I describe). When the cogs in my application come loose I'd like to replay the test using the Selenium IDE, letting me have full control over the action
But I'm not sure how to go from my test script back into the selenium IDE, you can't paste perl into the IDE and have it transmogrify back to "HTML" (aka, internal selenium language, aka selenese). It was easy enough getting it out, alas.
The RemoteRunner has the command history in it, and I can copy and paste from this directly into selenium ide, and that would be great, but the history box will only hold 5 or 6 lines and clears itself! So it taunts me and is useless.
So how to log these more effectively? The logging options for the selenium rc (-browserSideLog, -log) don't seem to be helpful in this regard. I'm thinking of finding its RemoteRunner.html and hacking at it maybe so it won't clear that list, but is there another way?
It seems to be a not very common task but very interesting one. I do not think that there's some standard way so something has to be implemented.
I do not know Perl much and I use Java, so this is just a heads up:
I would extend the DefaultSelenium class for my tests that will use extended HttpCommandProcessor that will logs all commands performed:
import com.thoughtworks.selenium.HttpCommandProcessor;
public class ExtHttpCommandProcessor extends HttpCommandProcessor {
public ExtHttpCommandProcessor(String serverHost, int serverPort,
String browserStartCommand, String browserURL) {
super(serverHost, serverPort, browserStartCommand, browserURL);
}
public String doCommand(String commandName, String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("|" + commandName + "|");
if (args!=null) {
for (String arg : args) {
sb.append(arg + "|");
}
if (args.length<2) {
sb.append(" |");
}
} else {
sb.append(" | |");
}
System.out.println(sb.toString());
// or log it where you want
return super.doCommand(commandName, args);
}
}
And
import com.thoughtworks.selenium.DefaultSelenium;
public class ExtSelenium extends DefaultSelenium {
public ExtSelenium(String serverHost, int serverPort,
String browserStartCommand, String browserURL) {
super(new ExtHttpCommandProcessor(serverHost, serverPort, browserStartCommand, browserURL));
}
}
Then I would extend SeleneseTestCase for use as the base in my tests:
import com.thoughtworks.selenium.SeleneseTestCase;
public class ExSeleneseTestCase extends SeleneseTestCase {
public void setUp(String url, String browserString) throws Exception {
int port = 4444;
if (url==null) {
url = "http://localhost:" + port;
}
selenium = new ExtSelenium("localhost", port, browserString, url);
selenium.start();
selenium.setContext(this.getClass().getSimpleName() + "." + getName());
}
}
The output of such test will look like:
|getNewBrowserSession|*iexplore|http://localhost:8080/|
|setContext|SimpleTest.testNew| |
|open|/webapp/test.html| |
|isTextPresent|Sample text| |
|click|sampleLink| |
|waitForPageToLoad|10000| |
|testComplete| | |
This solution will not log verifys and asserts so they may also be overrided in ExSeleneseTestCase to produce some trace.
You could also go the other way, which is probably easier: save the (partial) selenese HTML files when you generate them, and from the perl/java/... code, parse the files and execute the lines using doCommand. That way, you don't have to reconstruct the asserts/verify statements, because they weren't lost in the first place.