I would like to search Java annotations with another annotations inside. I don't know how many nested levels there are or I don't want to specify it. Finally, I would like to search for examples of #ApiImplicitParams with param type body and with #Example annotations inside.
But first I am trying to match anything nested.
First I searched for
#ApiImplicitParams(...)
and it found me somethind. The very first result is
#ApiImplicitParams({ #ApiImplicitParam(name = "foo", value = "List of strings", paramType = "body", dataType = "Foo") })
and has #ApiImplicitParam inside. Let's try to match it.
I tried
#ApiImplicitParams({#ApiImplicitParam(...) ...})
but it didn't find that case with one nesting and didn't find any cases with multiple #ApiImplicitParams inside.
How to accomplish?
Finally, I would like to search for examples of #ApiImplicitParams with param type body and with #Example annotations inside.
I believe the following query will meet your requirements here.
#ApiImplicitParams({...#ApiImplicitParam(...paramType = "body"...)...}) lang:Java
Some examples of matches --
#ResponseBody
#ApiImplicitParams({ #ApiImplicitParam(name = "foo", value = "List of strings", paramType = "body", dataType = "Foo") })
public Foo create(#RequestBody final Foo foo) {
nickname = "setLoggingSettings")
#ApiImplicitParams({
#ApiImplicitParam(
name = "Logging Config",
value = "Logging config to be updated",
required = true,
dataType = "com.yugabyte.yw.forms.PlatformLoggingConfig",
paramType = "body")
})
public Result setLoggingSettings() throws JoranException {
A note on this --
I don't know how many nested levels there are or I don't want to specify it.
The query provided above assumes one nested block, I'm afraid right now Sourcegraph doesn't have a good way to express an arbitrary level of nesting.
Hope that helps!
Related
I've got a Node module file containing about 100 exported methods, which looks something like this:
exports.methodOne = async user_id => {
// other method contents
};
exports.methodTwo = async user_id => {
// other method contents
fooMethod();
};
exports.methodThree = async user_id => {
// other method contents
fooMethod();
};
Goal: What I'd like to do is figure out how to grab the name of any method which contains a call to fooMethod, and return the correct method names: methodTwo and methodThree. I wrote a regex which gets kinda close:
exports\.(\w+).*(\n.*?){1,}fooMethod
Problem: using my example code from above, though, it would effectively match methodOne and methodThree because it finds the first instance of export and then the first instance of fooMethod and goes on from there. Here's a regex101 example.
I suspect I could make use of lookaheads or lookbehinds, but I have little experience with those parts of regex, so any guidance would be much appreciated!
Edit: Turns out regex is poorly-suited for this type of task. #ctcherry advised using a parser, and using that as a springboard, I was able to learn about Abstract Syntax Trees (ASTs) and the recast tool which lets you traverse the tree after using various tools (acorn and others) to parse your code into tree form.
With these tools in hand, I successfully built a script to parse and traverse my node app's files, and was able to find all methods containing fooMethod as intended.
Regex isn't the best tool to tackle all the parts of this problem, ideally we could rely on something higher level, a parser.
One way to do this is to let the javascript parse itself during load and execution. If your node module doesn't include anything that would execute on its own (or at least anything that would conflict with the below), you can put this at the bottom of your module, and then run the module with node mod.js.
console.log(Object.keys(exports).filter(fn => exports[fn].toString().includes("fooMethod(")));
(In the comments below it is revealed that the above isn't possible.)
Another option would be to use a library like https://github.com/acornjs/acorn (there are other options) to write some other javascript that parses your original target javascript, then you would have a tree structure you could use to perform your matching and eventually return the function names you are after. I'm not an expert in that library so unfortunately I don't have sample code for you.
This regex matches (only) the method names that contain a call to fooMethod();
(?<=exports\.)\w+(?=[^{]+\{[^}]+fooMethod\(\)[^}]+};)
See live demo.
Assuming that all methods have their body enclosed within { and }, I would make an approach to get to the final regex like this:
First, find a regex to get the individual methods. This can be done using this regex:
exports\.(\w+)(\s|.)*?\{(\s|.)*?\}
Next, we are interested in those methods that have fooMethod in them before they close. So, look for } or fooMethod.*}, in that order. So, let us name the group searching for fooMethod as FOO and the name of the method calling it as METH. When we iterate the matches, if group FOO is present in a match, we will use the corresponding METH group, else we will reject it.
exports\.(?<METH>\w+)(\s|.)*?\{(\s|.)*?(\}|(?<FOO>fooMethod)(\s|.)*?\})
Explanation:
exports\.(?<METH>\w+): Till the method name (you have already covered this)
(\s|.)*?\{(\s|.)*?: Some code before { and after, non-greedy so that the subsequent group is given preference
(\}|(?<FOO>fooMethod)(\s|.)*?\}): This has 2 parts:
\}: Match the method close delimiter, OR
(?<FOO>fooMethod)(\s|.)*?\}): The call to fooMethod followed by optional code and method close delimiter.
Here's a JavaScript code that demostrates this:
let p = /exports\.(?<METH>\w+)(\s|.)*?\{(\s|.)*?(\}|(?<FOO>fooMethod)(\s|.)*?\})/g
let input = `exports.methodOne = async user_id => {
// other method contents
};
exports.methodTwo = async user_id => {
// other method contents
fooMethod();
};
exports.methodThree = async user_id => {
// other method contents
fooMethod();
};';`
let match = p.exec( input );
while( match !== null) {
if( match.groups.FOO !== undefined ) console.log( match.groups.METH );
match = p.exec( input )
}
I struggle to find a solution for what is probably pretty simple, and despite I crawl a lot of questions, I can't manage to make it work.
Here are 2 HTML elements:
Test1
Test2
I want to get ONLY the content of the 1st element's href property (#content1). It must match because the html element contains no "onclick" property.
This regex works for matching the 1st element only:
^<a href="#"((?!onclick).)*$
but I can't figure out how to get the HREF content.
I've tried this:
^<a href="#(.*)"((?!onclick).)*$
but in this case, both elements are matching.
Thanks for your help !
I strongly suggest that you should do that in two steps. For one thing, parsing arbitrary html with a regexp is a notoriously slippery and winding road. For the other: there is no achievement in doing everything with one illegible regex.
And there's more to it: "contains no "onclick" attribute" is not the same as "href attribute is not directly followed by onclick attribute". So, a one-regex-solution would be either very complicated or very fragile (html tags have arbitrary attributes order).
var a = [
'Test1',
'Test2'
];
console.log(
a.filter(i => i.match(/onclick/i) == null)
.map(i => i.match(/href="([^"]+)"/i)[1]
)
This assumes that your href attribute values are valid and do not contain quotes (which is, of course, technically possible).
Regex is not made for this. JavaScript would work better. This code will store an array of the hrefs matching your requirements in the variable hrefArray.
var hrefArray = [];
for (var elem of document.getElementsByTagName('a')) {
if (elem.onclick) hrefArray.push(elem.href)
}
An example with your HTML is in the snippet below:
var hrefArray = [];
for (var elem of document.getElementsByTagName('a')) {
if (elem.onclick) hrefArray.push(elem.href)
}
console.log(hrefArray);
body {
background-color: gray;
}
Test1
Test2
I'm coming from a Javascript background & I'm trying to understand how I need to structure/build a program with Reason/Ocaml's module system.
As an exercise let's say I want to write this piece of javascript in OCaml/Reason (will compile it back to js through js_of_ocaml)
var TeaType = new GraphQLObjectType({
name: 'Tea',
fields: () => ({
name: {type: GraphQLString},
steepingTime: {type: GraphQLInt},
}),
});
How should I design my program to accomplish this?
Should I make a module which takes another module to produce a GraphQLObjectType in js through js_of_ocaml?
How would I structure this type that backs a GraphQLObjectType?
Tea.re
let name = "Tea";
let fields = /* what type should I make for this? Tea is
just one of the many graphql-types I'll probably make */
I mean fields is a thunk which returns a map that contains an unknown amount of fields. (every graphqlobject has different fields)
To what type does this map in OCaml/Reason, do I need to make my own?
Just for you to feel the flavor of OCaml, the direct (syntactic) translation would be:
let tea_type = GraphQL.Object.{
name = "Tea";
fields = fun () -> QraphQL.Field.[{
name = GraphQL.Type.{name : GraphQL.string }
steeping_time = GraphQL.Type.{name : QraphQL.int }
}]
}
Basically, I mapped js objects to OCaml's records. There are also objects in OCaml with methods and inheritance, but I think that records are still a closer abstraction. The records can be seen as a named tuple, and, of course, can contain functions. Modules, are more heavy weight abstractions, that is also a collection of fields. Unlike records, modules may contain types, other modules, and basically any other syntactic construction. Since types are removed at compile time, the runtime representation of a module is absolutely the same as the representation of records. Modules also define namespaces. Since OCaml records are defined by the names of their fields, it is always useful to define each records in its own module, e.g.,
module GraphQL = struct
let int = "int"
let string = "string"
module Type = struct
type t = {
name : string
}
end
module Field = struct
type t = {
name : string;
steeping_time : Type.t
}
end
module Object = struct
type t = {
name : string;
fields : unit -> Field.t list
end
end
So I'm using ui-router and stateparams to nest child states, and it works well. I'm now trying to find a way to dictate a css class what state level the app is at. main.route1.section1 would be 3 levels.
Here's some non-working code to help show:
<div ng-class="{findState().currentCount}"></div>
app.run(function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.findState = function() {
var currentName = $state.current.name;
var currentMatch = currentName.match(/./g);
$rootScope.currentCount = currentMatch.length;
};
});
I'm basically looking for a way to take $state.current.name which say equals main.route1.section1 and split it at the dot and count how many are in the array and return that number to the mg-class. Unless you have a better idea... like a regex filter?
Take a look of the object $state.$current (instead of $state.current). In particular, the property path : it's an array representing the state hierarchy of the current state.
So what you are looking for is : $state.$current.path.length
I'm pretty new to scala and basically I want to have a couple of functions coupled to a string in a hashmap.
However I get an error at subscribers.get(e.key)(e.EventArgs); stating Option[EventArgs => Unit] does not take parameters...
Example code:
object Monitor {
val subscribers = HashMap.empty[String, (EventArgs) => Unit ]
def trigger(e : Event){
subscribers.get(e.key)(e.EventArgs);
}
def subscribe(key: String, e: (EventArgs) => Unit) {
subscribers += key -> e;
}
}
The get method of a Map gives you an Option of the value, not the value. Thus, if the key if found in the map, you get Some(value), if not, you get None. So you need to first "unroll" that option to make sure there is actually a value of a function which you can invoke (call apply on):
def trigger(e: Event): Unit =
subscribers.get(e.key).foreach(_.apply(e.EventArgs))
or
def trigger(e: Event): Unit =
subscribers.get(e.key) match {
case Some(value) => value(e.EventArgs)
case None =>
}
There are many posts around explaining Scala's Option type. For example this one or this one.
Also note Luigi's remark about using an immutable map (the default Map) with a var instead.
Since the get method returns Option, you can use 'map' on that:
subscribers.get(e.key).map(f => f(e.EventArgs))
or even shorter:
subscribers.get(e.key) map (_(e.EventArgs))
get only takes one argument. So subscribers.get(e.key) returns an Option, and you're trying to feed (e.EventArgs) to that Option's apply method (which doesn't exist).
Also, try making the subscribers a var (or choosing a mutable collection type). At the moment you have an immutable collection and an immutable variable, so your map cannot change. A more idiomatic way to declare it would be
var subscribers = Map[String, EventArgs => Unit]()
HashMap.get() in Scala works in a bit different way, than in Java. Instead of returning value itself, get() returns Option. Option is a special type, that can have 2 values - Some(x) and None. In first case it tells "there's some value with such a key in a map". In second case it tells "nope, there's nothing (none) for this key in a map". This is done to force programmers check whether map actually has an object or not and avoid NullPointerException, which appears so frequently in Java code.
So you need something like this:
def trigger(e: Event) {
val value = subscribers.get(e.key)
value match {
case None => throw new Exception("Oops, no such subscriber...")
case Some(f) => f(e.EventArgs)
}
}
You can find more info about Option type and pattern matching in Scala here.