We have a tool that generates the source code (for C#, Java, IOS, etc.) from a given model. The code is manually edited for any feature that is missing by the code generator. Whenever any changes made to the model and needs to generate the source code out of it, the manual changes that performed on the previous version are lost.
In order to minimize the loss, the user edited code blocks (methods, classes, properties, etc.) are marked with a custom attribute (say CUSTCODE). While generating the source for the new version, if a path for previous version is mentioned (by user), system will compare the two source codes and merge the contents as follows (previous version is considered as the base in this case):
Remove any code blocks that are available in previous version and not available in new version, which are not marked as CUSTCODE.
Replace any code blocks that are available in both the versions, and not marked as CUSTCODE with latest version code.
Add the missing code blocks from the latest code.
For this, we are using Microsoft Roslyn and is working as expected for C# (of course additional checks like usings are performed)
[Note: I can use Java / C# for the merger app. The system is going to invoke any app by passing params. The same is achieved using ASTRewriter for Java]
Now the challenge is for the JS and HTML. Currently We are focusing at JS.
We have checked several AST JavaScript parsers like Rhino, IronJS, astify etc. But I am blocked at some point in using them.
So I want to build a custom merger. Since JavaScript is so dynamic, we are (going to) setting up the guidelines for JS code.
Enclose all the code within a named function, which acts as unique identifier to match and merge.
Add a comment with "CUSTCODE" on top of the method when system need to keep the function intact while merge.
Our intention is to follow the following approach:
Move the anonymous functions found in jQuery into named functions and call them in jQuery
Name any anonymous function like var v = function()...
Wrap all jQueries and standalone pieces of code into named self executable functions while keeping the order intact.
Move all global variables to top of the JS file. (Do not enclose in any function)
The merging process works as follows:
Capture all strings (single quote, double quote), comments (inline, block) and replace with some unique identifiers. (Except the ones tagged with "CUSTCODE"
Capture the function body (based on the count of '{' and '}') and replace with unique identifier. Read the previous line, mark the method if it is "CUSTCODE"
Compare and replace the captured function bodies with latest version content appropriately.
Restore all captures to generate the final output.
I am wondering if anything else I need to consider.
Related
I need to remove a particular function or a class from my Java code when it is being converted into .jar file using Maven. But the caveat is the function or class should stay inside the source code.
Is there any such way in which I can achieve this using Maven and/or any Java utilities?
(there are a lot of functions ~400 and their implementations are very large as well therefore commenting the code is not an option)
Okay, so the real problem is this:
We have a code base which includes certain parts that are not currently being used, but they may be used in the future, so we want to keep them in the code base, but we do not want them to be shipped to customers. (Due to, uhm, reasons.) What are the best practices for achieving this? Note that commenting them out would be impractical.
The proper way to achieve this is to extract all those parts into a separate module, and refrain from shipping that module.
The hacky way is to use a hard-coded feature flag.
A normal (non-hard-coded) feature flag is a boolean which controls a certain aspect of the behavior of our software. For example, if you build an mp3 player application, and you want to add support for the aac file format, but you do not want to ship support for it yet, then you might want to create a boolean supportAacFeatureFlag() method, and have all code that pertains to the aac file format invoke that method and check the return value before doing anything. It is important to note that this must be a method, not a constant, so that its value is not known at compilation time, because every single if statement that checks the value of a constant is bound to yield a "condition is always true" or "condition is always false" warning. The great benefit of feature flags over commenting-out code is that the code controlled by a feature flag must still compile, so it must be semantically correct. The problem with feature flags is that they do not eliminate the code; the code still gets shipped, it just does not get executed.
A hard-coded feature flag is a feature flag which is implemented using a constant. The constant condition warning will be issued in every single use of that flag, so it will have to be globally disabled. (That's why this approach is hacky: we normally want all warnings enabled.) The benefit of using a constant is that its value is known at compilation time, so even though the compiler will still compile the controlled code, it will refrain from emitting any bytecode for it, so the code essentially does not get shipped to customers. Only empty functions get shipped.
Note that this is documented behavior of the Java compiler. In other languages like C++ and C# the compiler always emits all code, and you have to use other means of controlling code generation, like #defined symbols, which, in my opinion, are also very hacky.
An alternative way which I am sure some people will opt for but I would strongly advice against is to keep the unused code in a separate feature branch and remove it from the master branch. I would strongly advise against this, because any refactorings applied to the master branch will not affect the feature branch, so the code will diverge, so it will be a nightmare to integrate it in the future.
I'm currently trying to replace an old (java) testing framework with a different, although similar, one. Therefore, as most occurences of old framework code are the same 90% of the time (in the sense of identic variable names, parameter types etc.), replacing them is pretty straightforward and rather repetitive.
Therefore, I wrote myself a few regex matches (which work just fine, they are not the focus of this question).
However, I have a rather large number of different test files, and I already at this point - just having started - have 6 different match/replacement-pairs that I would like to apply.
Now obviously, being a computer scientist, I would love to automate this, instead of going through every file, pressing Ctrl+F, pasting the matching regex, pasting the replacement regex, pressing the replace button, repeating this cycle 5 more time, and then moving to the next file.
So, let's say for the sake of simplicity, that these are my regexes:
//matches the existing framework
OldClass (.*?) = new OldClass("string");
//replacement regex:
NewClass $1 = new NewClass("string");
//example replacement:
OldClass foo = new OldClass("string");
//becomes:
NewClass foo = new NewClass("string");
So, If I want to replace several of these match/replace-pairs in lots of different files - can I use any built-in eclipse function, or is there an extension that provides this functionality?
Note that I'm aware that I could write a simply java program that just skims through all my source code and applies the regexes as desired.
I'd much rather avoid spending that time, though, and especially would also like to get a chance to apply them individually to each file, so I can re-run the tests afterwards and make sure nothing is broken - which will happen, as not all of the old framework code can be replaced automatically, due to too complex & specific cases. Since I'm also removing the old imports, though, this will break any still existing non-replaced code relying on now-no-longer-existing imports.
Eclipse should have a simple file search option with a "Replace.." button at the bottom. You can search as you would normally specifying the file endings that you'd like to search (probably in this case you'd want *.java). The replace button lets you replace each search result with a replacement using regular expressions.
Granted, this will change your source one replace at a time and that is awkward I know, but my recommendation is to perform small steps, minimizing time in which your code is broken. For instance if you move your class to a new location with a new name, just focus on renaming the class first (verifying that the code then works afterwards), and only then focus on changing its package.
Word to the wise, click Preview first!
Alternatively, consider using ctrl+shift+R to rename methods/variables/classes. Assuming the code is under a source folder, it will automatically rename everywhere it is used. Generally it is preferable to using regular expressions. But again, you can't perform multiple changes at the same time. Though this is probably for the best. Just make a backup of the project and organize the changes that need to be made before starting.
Good luck!
I have generated a Java API from some Protocol Buffers source code. You can see it here: https://microbean.github.io/microbean-helm/apidocs/ Things in the hapi.* package hierarchy are generated. The semantics of this API don't matter for this question.
As part of working with this API, I need to assemble a Chart.
With Protocol Buffers, when you are creating or mutating things, you work with "builders". These builders have a build() method that returns the (immutable) object that they are responsible for building. That's fine. Consequently, in this generated API a Chart.Builder builds Charts.
In this generated API, a Chart.Builder has "sub-" Chart.Builders that it contains. The list of such sub-builders is known as its dependencies and is represented via a smattering of generated methods. I'll point out two interesting ones:
addDependencies that takes a Chart.Builder
addDependenciesBuilder that takes no arguments and returns the current Chart.Builder
(I'll start by saying I have no idea what the second method is good for. It appears to stuff a new builder into an internal list and then...that's it.)
In the first method's case, if I hand it a Chart.Builder, this should add it. Just what I needed!
OK, but now I don't want to add a Chart.Builder if it's already present. How can I reliably check for the presence of a sub-builder in a top-level builder? More generally, in a Protocol Buffers Java API, how can I check for a builder inside a List of builders?
(I understand I can roll my own "equality" checker, but I'm wary that perhaps I'm off in the wrong patch of weeds altogether: maybe this isn't how you construct an object graph using Protocol Buffers-generated code?)
You would think that I could call the getDependenciesBuilderList() method, and see if it contains my candidate builder. But I've found this doesn't work: java.util.List#contains(Object) will return false for any builder passed in.
Surely this very simple treat-a-list-as-a-set pattern has a solution when working with Java APIs generated from .proto files? If so, I'm failing to see it. How can I do what I want?
(For further reading, I've gone through https://developers.google.com/protocol-buffers/docs/javatutorial which treats the subject in a fairly cursory fashion.)
I have a relatively complex java project, with many classes that are probably not used.
Static analysis of the code base is relevant for some of the classes, but some are loaded dynamically (network services, persisted data, etc.)
Is there a method to get a list of deprecated classes that were actively used in the jvm, so I can know if those classes are used?
[I know there may be "sleeper classes" that are used only rarely, but that's a risk I can take]
The JVM may have an option to print information about all used classes. For example:
java -verbose:class ...
You still would have to filter out the deprecated ones by some other means.
You can try to compile with -deprecation (or -Xlint:deprecation) to see the uses of deprecated APIs if you have to sourcecode (I guess you have it)
I could think of the following :
Add static initializer to each of your classes in the form
static {
// here you can get creative :
// either do some writing to a file with each class printing its name
// or do System.err outputing the class name, then later fetching the entire output.
}
If you are too lazy to manually add the piece of code you could write simple program to append this initializer to all files ending with .java.
This is simple way of getting a list of all the classes that are being used ( I think).
Best of luck!
There are tools like UCDetector which I've used in the past. But that requires manual assessments which can be painful for large projects. You can do text analysis like below:
Listing active usage deprecated methods
For static code analysis, list down deprecated methods of which source is already available using an IDE.
In Eclipse, goto Window -> Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API : Set level to WARNING and check the items besides.
In Problems view, click the down button near the tab -> Group By -> Java Problem Type
You will be able to see Deprecation usage list grouped together, copy the contents as text, which you can use to further prepare scripts/excel for analysis
Use a simple text editor to find and replace "from the type " and " is deprecated" with tab characters
Copy the contents to a spreadsheet. You will have a list of classes which contain deprecated methods but have active usage.
Listing inactive usage deprecated methods
List down the class and method names by using similar approach above (For method name replace the text "The method " and " from the type " with tab characters).
This list minus the previous list is the inactive methods list.
Listing dynamic deprecated methods
For dynamic code using reflections etc, there is no single bullet approach. You can do filtering of basic stuff using the method names.
List down the method names by using similar approach above (Replace the text "The method " and " from the type " with tab characters).
For the unique set of method names, loop to use a grep script. This type of search can be slow even for small projects. But just in case you 'ld want to invest the time.
Remove them all and try to run your application. Every time you get a ClassNotFoundException for one of them, write it down and add the class back. Rinse and repeat.
I have a multilingual web application that gets all of the translations from a single object, for example lang.getTranslation("Login") and the object is responsible for finding the translation in an xml file in the user's language.
What I'd like to do is a script / custom static analysis that outputs all the missing translations and translations that are no more used in the application. I believe I should start by programmatically finding every call to the getTranslation method and the string parameter, storing the data in a special structure and comparing it to all the translation files.
Is there a library that will allow me to do this easily? I already found Javassist but I can't use it to read the parameter values. I also tried grepping, but I'm not sure if that's a robust solution (in case there will be a call to another class that has a getTranslation method). I know Qt has a similar mechanism for finding translatable strings in the code, but that's a totally different technology..
I'm asking this because I'm quite sure there's a good existing solution for this and I don't want to reinvent the wheel.
Ok, here's how I did it. Not the optimal solution, but works for me. I created a utility program in Java to find all the method calls and compare the parameters to existing translations.
Find all classes in my project's root package using the Reflections library
Find all getTranslation method calls of the correct class in the classes using the Javassist library and create a list of them (contains: package, class, row number)
Read the appropriate .java files in the project directory from the given row until the ';' character
Extract the parameter value and add it to a list
Find the missing translations and output them
Find the redundant translations and output them
It took me a while to do this, but at least I now have a reusable utility to keep the translation files up to date.