Thanks.
public class ParameterNameConvention extends AbstractJavaRule {
private final static String PATTERN = "[p][a-zA-Z]+";
public Object visit(ASTMethodDeclaration node, Object data) {
RuleContext result = (RuleContext) data;
String rulePattern = (!getStringProperty("rulePattern")
.equalsIgnoreCase("")) ? getStringProperty("rulePattern")
: PATTERN;
if (node.containsChildOfType(ASTFormalParameter.class)) {
Iterator iterator = node.findChildrenOfType(
ASTFormalParameter.class).iterator();
while (iterator.hasNext()) {
ASTFormalParameter element = (ASTFormalParameter) iterator
.next();
Iterator decIdIterator = element.findChildrenOfType(
ASTVariableDeclaratorId.class).iterator();
while (decIdIterator.hasNext()) {
ASTVariableDeclaratorId decElement = (ASTVariableDeclaratorId) decIdIterator
.next();
if (!decElement.getImage().matches(rulePattern)) {
result.getReport()
.addRuleViolation(
new RuleViolation(
this,
node.getBeginLine(),
"Parameter '"
+ decElement.getImage()
+ "' should match regular expression pattern '"
+ rulePattern + "'",
result));
}
}
}
}
return result;
}
}
For the new RuleViolation there is a problem:
The constructor RuleViolation(ParameterNameConvention, int, String, RuleContext) is undefined
Why?
What version of PMD are you using? IN PMD 4.2.5, the constructors for RuleViolation are:
RuleViolation(Rule rule, RuleContext ctx, SimpleNode node)
RuleViolation(Rule rule, RuleContext ctx, SimpleNode node, java.lang.String specificMsg)
Your code doesn't match either of these.
Related
public static void findAll(Handler<AsyncResult<ChannelInfo[]>> ar)
{
//getConnection().query("SELECT &", arg1)
getConnection().queryWithParams("SELECT * FROM Servers", new JsonObject(), res -> {
if (res.succeeded() && res.result().size() > 0) {
ChannelInfo[] channels = new ChannelInfo[res.result().size()];
int count = 0;
for (JsonObject row : res.result()) {
channels[count++] = new ChannelInfo()
.setId(row.getInteger("srv_id"))
.setName(row.getString("srv_name"))
.setIp(row.getString("srv_ip"))
.setServerDomain(row.getString("srv_domain"))
.setPort(row.getInteger("srv_port"))
.setPosition(row.getInteger("srv_position"))
.setPromiseToFightFlag(row.getBoolean("srv_promise_to_fight_flag"))
.setMoreServerFlag(row.getBoolean("srv_more_server_flag"))
.setMaxRoom(row.getInteger("srv_max_room"))
.setNumber(row.getInteger("srv_number"))
.setAllowedRoomTypeId(row.getInteger("srv_allowed_room_type_id"))
.setLimitMinLV(row.getInteger("srv_limit_min_lv"))
.setLimitMaxLV(row.getInteger("srv_limit_max_lv"))
.setMaxClient(row.getInteger("srv_max_client"));
}
ar.handle(Future.succeededFuture(channels));
} else {
logger.error("Erro ao obter um usuário pelo nome", res.cause());
ar.handle(Future.failedFuture(res.cause()));
}
});
}
error: The method queryWithParams(String, JsonArray, Handler>) in the type SQLConnection is not applicable for the arguments (String, JsonObject, ( res) -> {})
Replace ...
getConnection().queryWithParams("SELECT * FROM Servers", new JsonObject(), res ...
... with:
getConnection().queryWithParams("SELECT * FROM Servers", new JsonArray(), res ...
The method queryWithParams expects the following arguments:
the query string
the query parameters
a handler for dealing with the response
The second argument must be a JsonArray not a JsonObject. In your case you don't appear to be passing in any parameters so supplying an empty JsonArray (e.g. new JsonArray()) should suffice.
I want to create a macro that generates this code for me:
if (myEntity.get(Attack) == null) myEntity.add(new Attack());
if (myEntity.get(Confused) == null) myEntity.add(new Confused());
if (myEntity.get(Defend) == null) myEntity.add(new Defend());
if (myEntity.get(Offense) == null) myEntity.add(new Offense());
In code I'd like to declare/use it like this:
EntityMacroUtils.addComponents(myEntity, Attack, Confused, Defend, Offense);
The current macro function looks like this:
macro public static function addComponents(entity:ExprOf<Entity>, components:Array<ExprOf<Class<Component>>>):Expr
{
var exprs:Array<Expr> = [];
for (componentClass in components)
{
var instance = macro $e { new $componentClass() }; // problem is here
var expr = macro if ($entity.get($componentClass) == null) $entity.add(instance);
exprs.push(expr);
}
return macro $b{ exprs };
}
This macro function is incorrect, I get the error:
EntityMacroUtils.hx:17: characters 22-43 : Type not found : $componentClass
The problem is I don't know how to define new $componentClass(). How would I solve this?
I also want to avoid to have Type.createInstance in the output code.
One way to programmatically generate instantiation code is by using "old school" enums AST building (compatible Haxe 3.0.1+):
// new pack.age.TheClass()
return {
expr:ENew({name:"TheClass", pack:["pack", "age"], params:[]}, []),
pos:Context.currentPos()
};
An improved syntax using reification is possible:
// new pack.age.TheClass()
var typePath = { name:"TheClass", pack:["pack", "age"], params:[] };
return macro new $typePath();
Now, for a convenient "instantiation helper" function syntax, we need to do some contorsions to extract a type path from the expression we receive in the macro function:
// new Foo(), new pack.Bar(), new pack.age.Baz()
instantiate(Foo, pack.Bar, pack.age.Baz);
macro static function instantiate(list:Array<Expr>)
{
var news = [for (what in list) {
var tp = makeTypePath(what);
macro new $tp();
}];
return macro $b{news};
}
#if macro
static function makeTypePath(of:Expr, ?path:Array<String>):TypePath
{
switch (of.expr)
{
case EConst(CIdent(name)):
if (path != null) {
path.unshift(name);
name = path.pop();
}
else path = [];
return { name:name, pack:path, params:[] };
case EField(e, field):
if (path == null) path = [field];
else path.unshift(field);
return makeTypePath(e, path);
default:
throw "nope";
}
}
#end
In case anyone is in need for answers, I got this Thanks to ousado on the Haxe IRC chat:
If you do it in macro alone you can do this:
var ct = macro : pack.age.SomeTypename;
var tp = switch ct { case TPath(tp):tp; case _: throw "nope"; }
var expr = macro new $tp();
..or, if you explicitly construct tp:
var tp = {sub:'SomeTypeName',params:[],pack:['pack','age'],name:"SomeModuleName"}
As you can see, the complex type path is explicitly given here.
Unfortunately, Haxe don't really have a concise syntax for types in expression positions. You can pass ( _ : TypeName ) to provide an expression that contains a ComplexType.
But if you want to pass a type as argument, you could do it like this:
import haxe.macro.Expr;
using haxe.macro.Tools;
class Thing {
public function new(){}
}
class OtherThing {
public function new(){}
}
class TMacroNew {
macro static function instances( arr:Array<Expr> ) {
var news = [for (e in arr) {
var ct = switch e.expr { case EParenthesis({expr:ECheckType(_,ct)}):ct; case _: throw "nope"; };
var tp = switch ct { case TPath(tp):tp; case _: throw "nope"; };
macro new $tp();
}];
trace( (macro $b{news}).toString());
return macro $b{news};
}
static function main(){
instances( (_:Thing), (_:Thing), (_:OtherThing) );
}
}
..if you want a list of types, you might want to go for a parameter list like ( _ : L< One,Two,Three> ).
The accepted answer is problematic because it breaks when type parameters are involved, or when support for non-nominal types should be included.
I updated the example using two alternatives for a more concise notation for the list of types, while still allowing syntax for actual types.
import haxe.macro.Expr;
using haxe.macro.Tools;
class Thing {
public function new(){}
}
class OtherThing {
public function new(){}
}
class TPThing<T>{
public function new(){}
}
class TMacroNew {
macro static function instances( e:Expr ) {
var tps = switch e.expr {
case EParenthesis({expr:ECheckType(_,TPath({params:tps}))}):tps;
case ENew({params:tps},_):tps;
case _: throw "not supported";
}
var type_paths = [ for (tp in tps) switch tp {
case TPType(TPath(tp)):tp;
case _: throw "not supported";
}];
var news = [for (tp in type_paths) macro new $tp()];
trace( (macro $b{news}).toString());
return macro $b{news};
}
static function main(){
instances( (_:L<Thing,Thing,OtherThing,TPThing<Int>> ) );
instances( new L<Thing,Thing,OtherThing,TPThing<Int>>() );
}
}
Edit:
The L in L< ... > could be any valid type name. Its only purpose is allowing to write a comma-separated list of types in valid syntax. Since macro functions take expressions as arguments, we have to use an expression that allows/requires a type, like: ( _ :T ), new T(), var v:T, function(_:T):T {}.
I am trying to build generic sort method using Expressions.
I came up with the following method. For some reasons the code is breaking at the statement when a nested property is used in the sort expression.
var sortExpression = Expression.Lambda<Func<T, object>>
(Expression.Convert(Expression.Property(sortParam, sortColumn), typeof(object)), sortParam);
private static IQueryable<T> SortQuery<T>(IQueryable<T> query, string sortColumn)
{
if (!string.IsNullOrEmpty(sortColumn))
{
var sortParam = Expression.Parameter(typeof(T), "x");
Expression expr = sortParam;
foreach (var prop in sortColumn.Split('.'))
{
expr = Expression.PropertyOrField(expr, prop);
}
var sortExpression = Expression.Lambda<Func<T, object>>
(Expression.Convert(Expression.Property(sortParam, sortColumn), typeof(object)), sortParam);
return query.OrderBy(sortExpression);
}
return null;
}
Any idea where I am doing it wrong ?
Try:
private static readonly MethodInfo OrderBy = (from x in typeof(Queryable).GetMethods()
where x.Name == "OrderBy"
let pars = x.GetParameters()
where pars.Length == 2
select x).Single();
private static IQueryable<T> SortQuery<T>(IQueryable<T> query, string sortColumn)
{
if (!string.IsNullOrEmpty(sortColumn))
{
var sortParam = Expression.Parameter(typeof(T), "x");
Expression expr = sortParam;
foreach (var prop in sortColumn.Split('.'))
{
expr = Expression.PropertyOrField(expr, prop);
}
var lambda = Expression.Lambda(expr, sortParam);
var orderBy = OrderBy.MakeGenericMethod(typeof(T), expr.Type);
return (IQueryable<T>)orderBy.Invoke(null, new object[] { query, lambda });
}
return null;
}
You have to use reflection to invoke the Queryable.OrderBy. In general, casting to object doesn't work very well with Entity Framework/LINQ to SQL, so you can try it, but there is only a very little chance it will work.
I've Been Trying to change the order of nodes through quickfix, but something is wrong.
Here's my code in xtend:
#Fix(org.xtext.custom.conventions.validation.ConventionsValidator::CONVENTION_NOT_ORDERED)
def fixFeatureName( Issue issue, IssueResolutionAcceptor acceptor){
acceptor.accept(issue, 'Sort', "Sort '" + issue.data.head + "'", null)[
element, context |
var gr=(element as Greeting)
if (gr.name === null || gr.name.length === 0)
return;
var econt=gr.eContainer.eContents
var comparator = [ EObject obj1, EObject obj2 |
var o1 = (obj1 as Greeting)
var o2 = (obj2 as Greeting)
return o1.name.compareTo(o2.name)
]
ECollections::sort(econt, comparator)
]
}
No exception is being thrown to console, in debug I found an UnsupportedOperationException is thrown and handled by xtext.
I suspect that EList is immutable.
So how can I sort the AST?
(Here is the generated code: )
#Fix(ConventionsValidator.CONVENTION_NOT_ORDERED)
public void fixFeatureName(final Issue issue, final IssueResolutionAcceptor acceptor) {
String[] _data = issue.getData();
String _head = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(_data)));
String _plus = ("Sort \'" + _head);
String _plus_1 = (_plus + "\'");
final ISemanticModification _function = new ISemanticModification() {
public void apply(final EObject element, final IModificationContext context) throws Exception {
Greeting gr = ((Greeting) element);
boolean _or = false;
String _name = gr.getName();
boolean _tripleEquals = (_name == null);
if (_tripleEquals) {
_or = true;
} else {
String _name_1 = gr.getName();
int _length = _name_1.length();
boolean _tripleEquals_1 = (Integer.valueOf(_length) == Integer.valueOf(0));
_or = (_tripleEquals || _tripleEquals_1);
}
if (_or) {
return;
}
EObject _eContainer = gr.eContainer();
EList<EObject> econt = _eContainer.eContents();
final Function2<EObject,EObject,Integer> _function = new Function2<EObject,EObject,Integer>() {
public Integer apply(final EObject obj1, final EObject obj2) {
Greeting o1 = ((Greeting) obj1);
Greeting o2 = ((Greeting) obj2);
String _name = o1.getName();
String _name_1 = o2.getName();
return _name.compareTo(_name_1);
}
};
Function2<EObject,EObject,Integer> comparator = _function;
final Function2<EObject,EObject,Integer> _converted_comparator = (Function2<EObject,EObject,Integer>)comparator;
ECollections.<EObject>sort(econt, new Comparator<EObject>() {
public int compare(EObject o1,EObject o2) {
return _converted_comparator.apply(o1,o2);
}
});
}
};
acceptor.accept(issue, "Sort", _plus_1, null, _function);
}
thanks!
Sorting a temporary collection which will then replace econt didn't work. but I managed to solve it in a different way.
so one solution was to force a cast of eContainer as it's runtime element (which is Model), and then getting a list with it's getGreetings getter, and with that element the sorting works, but I didn't want to involve non-generic code, for technical reasons.
So after a lot of experiments I finally found that element without involving any other elements or keywords from the grammar:
var econt = (gr.eContainer.eGet(gr.eContainingFeature) as EObjectContainmentEList<Greeting>)
and that is exactly what was looking for. Sorting is successful!
Here's the resulting Xtend code (got rid of casing in the comperator as well):
#Fix(ConventionsValidator::CONVENTION_NOT_ORDERED)
def fixFeatureName(Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, 'Sort', "Sort '" + issue.data.head + "'", null) [
element, context |
var gr = (element as Greeting)
if (gr.name === null || gr.name.length === 0)
return;
var econt = (gr.eContainer.eGet(gr.eContainingFeature) as EObjectContainmentEList<Greeting>)
var comparator = [ Greeting o1, Greeting o2 |
return o1.name.compareTo(o2.name)
]
ECollections::sort(econt, comparator)
]
}
and the generated java:
#Fix(ConventionsValidator.CONVENTION_NOT_ORDERED)
public void fixFeatureName(final Issue issue, final IssueResolutionAcceptor acceptor) {
String[] _data = issue.getData();
String _head = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(_data)));
String _plus = ("Sort \'" + _head);
String _plus_1 = (_plus + "\'");
final ISemanticModification _function = new ISemanticModification() {
public void apply(final EObject element, final IModificationContext context) throws Exception {
Greeting gr = ((Greeting) element);
boolean _or = false;
String _name = gr.getName();
boolean _tripleEquals = (_name == null);
if (_tripleEquals) {
_or = true;
} else {
String _name_1 = gr.getName();
int _length = _name_1.length();
boolean _tripleEquals_1 = (Integer.valueOf(_length) == Integer.valueOf(0));
_or = (_tripleEquals || _tripleEquals_1);
}
if (_or) {
return;
}
EObject _eContainer = gr.eContainer();
EStructuralFeature _eContainingFeature = gr.eContainingFeature();
Object _eGet = _eContainer.eGet(_eContainingFeature);
EObjectContainmentEList<Greeting> econt = ((EObjectContainmentEList<Greeting>) _eGet);
final Function2<Greeting,Greeting,Integer> _function = new Function2<Greeting,Greeting,Integer>() {
public Integer apply(final Greeting o1, final Greeting o2) {
String _name = o1.getName();
String _name_1 = o2.getName();
return _name.compareTo(_name_1);
}
};
Function2<Greeting,Greeting,Integer> comparator = _function;
final Function2<Greeting,Greeting,Integer> _converted_comparator = (Function2<Greeting,Greeting,Integer>)comparator;
ECollections.<Greeting>sort(econt, new Comparator<Greeting>() {
public int compare(Greeting o1,Greeting o2) {
return _converted_comparator.apply(o1,o2);
}
});
}
};
acceptor.accept(issue, "Sort", _plus_1, null, _function);
}
For example
class xx
{
public string name
{
get {return "";}
}
}
class yy
{
public string name(string n)
{
return "";
}
public string name(string n,ref string m)
{
return "";
}
public string name(string n,string m,ref xx k)
{
return "";
}
}
How to get "name" method by reflection technology ?
There's no easy way to do it using GetMethod. However, you can easily do it with GetMethods and Linq :
var methodInfo = from m in typeof(yy).GetMethods()
where m.Name == "name"
let prms = m.GetParameters()
where prms.Length == 3
&& prms[0].ParameterType == typeof(string)
&& prms[1].ParameterType == typeof(string)
&& prms[2].ParameterType == typeof(xx).MakeByRefType()
select m;
You could use Type.MakeByRefType()-Method to create an ref type param. The rest is done by reflection classes.
var method = typeof(yy).GetMethod(
"name",
new[] {typeof(string), typeof(string).MakeByRefType()});