Is it possible to change keyword for cross referencing between grammar rules/objects in Xtext? - dsl

When I want to make cross referencing between grammar rules in Xtext work, I need to use keyword name for that. E.g.:
Constant:
name=NAME_TERMINAL "=" number=Number;
ConstUsage:
constant=[Constant | NAME_TERMINAL];
Is it possible to change this word to another one (e.g. id) ? I need it e.g. in case when I have rule, which uses parameter name for something else.

you can use a custom implementation of IQualifiedNameProvider e.g. by subclassing DefaultDeclarativeQualifiedNameProvider.
public class MyDslQNP extends DefaultDeclarativeQualifiedNameProvider{
QualifiedName qualifiedName(Element e) {
Package p = (Package) e.eContainer();
return QualifiedName.create(p.getName(), e.getId());
}
}
see https://dietrich-it.de/xtext/2011/07/16/iqualifiednameproviders-in-xtext-2-0.html for the complete example

Related

IntelliJ Live Template for dart named constructor: lists class' fields

I want to generate a custom named constructor in Dart.
I have many dto class to implement and each should provide a named constructor like: ClassName.fromMap().
For example for this class:
class Student {
final String name;
final int age;
}
The generated constructor should be:
Student.fromMap(Map<String, dynamic> map) :
name = map['name'],
age = map['age'];
How can I retrieve the list of the field of my current class as strings? Is that even possibile?
Of course I can have a variable number of fields.
My template looks like:
$CLASS$.fromMap(Map<String, dynamic> map) :
$INITIALIZATION_LIST$
binding $CLASS$ to dartClassName().
Now I'd like to bind $INITIALIZATION_LIST$ to something like:
getClassFieldList().forEach((fieldName) => "$fieldName = map['$fieldName']")
Can I achieve something like that?
There is no way to retrieve a list of Dart class fields using predefined live template functions. You can try developing your own template macro for this. See https://intellij-support.jetbrains.com/hc/en-us/community/posts/206201699-create-a-new-expression-for-a-live-template-for-actionscript for some hints.
Existing live template functions implementations can be found at https://github.com/JetBrains/intellij-community/tree/master/platform/lang-impl/src/com/intellij/codeInsight/template/macro.
You can also try using Structural Search and Replace instead of live template

Puppet: how can i pass value from inherited class to base class?

How can I pass value from inherited class to base class using puppet?
You can see below a simplified code for my trials.
class executor::app($base_dir = "/usr/local",
$run_command = undef,
$prefix_naming = undef) {
}
class app1(
$base_dir = ::app1::params::base_dir,
$prefix_naming = "reader",
$run_command = " ") inherits executor::app{
}
OK, for starters lets assume you have these classes in module format. If not, then that should be the first order of business.
Second, avoid inheritance. There is almost always a better way to do it. Especially don't inherit across modules. About the only time I can think it's useful is for defaulting class parameters.
The base_dir on class app1 will not get the default unless the class inherits cea::params::base_dir (leading :: not needed). Again, across modules shouldn't be done. app1::params much better -- or just put in a sane default and eliminate the need to inherit parameters all together.
For your actual question, if you want to get a variable in another class you can just reference it. Keep in mind that puppet doesn't guarantee compile order so you should tell it to evaluate the other class first:
class executor::app {
Class['app1'] -> Class['executor::app']
$other_app_var = $app1::base_dir
}
Or throw this data in hiera and look up the value.

Declare a constant class field

I'm supposed to declare a class field for a federal tax rate, which is a constant, with a value .07. How can I achieve this?
Since you didn't specify a language, I'll throw in a Java solution
public class YourClass {
public static final double TAX_RATE = 0.07;
}
In Java naming convention, you name your constants with all upper casing and use _ to separate words instead of the normal camel casing.
the final keyword, is to make it, well, final - meaning unchangeable
Anything not withing a block like a constructor or a method is considered a field.

ANTLR4 Tokenizing a Huge Set of Keywords

I want to embed some known identifier names into my grammar e.g. the class names of my project are known and I want to tell the lexer what identifiers are known keywords that actually belongs to the class-name token. But since I have a long list of class names (hundreds of names), I don't want to create a class-name lexer rule by listing all the known class name keywords in the rule, that will make my grammar file too large.
Is it possible to place my keywords into a separate file? One possibility I am thinking about is to place the keywords in a java class that will be subclassed by the generated lexer class. In that case, my lexer's semantic predicate can just call a method in custom lexer superclass to verify if the input token matches my long list of names. And my long list can be placed inside that superclass src code.
However, in the ANTLR4 book it says grammar options 'superClass' for combined grammar only set the parser's superclass. How can I set my lexer's superclass if I still want to use combined grammar. Or is there any other better method to put my long list of keywords into a separate "keyword file".
If you want each keyword to have its own token type, you can do the following:
Add a tokens{} block to the grammar to create tokens for each keyword. This ensures unique token types are created for each of your keywords.
tokens {
Keyword1,
Keyword2,
...
}
Create a separate class MyLanguageKeywords similar to the following:
private static final Map<String, Integer> KEYWORDS =
new HashMap<String, Integer>();
static {
KEYWORDS.put("keyword1", MyLanguageParser.Keyword1);
KEYWORDS.put("keyword2", MyLanguageParser.Keyword2);
...
}
public static int getKeywordOrIdentifierType(String text) {
Integer type = KEYWORDS.get(text);
if (type == null) {
return MyLanguageParser.Identifier;
}
return type;
}
Add an Identifier lexer rule to your grammar that handles keywords and identifiers.
Identifier
: [a-zA-Z_] [a-zA-Z0-9_]*
{_type = MyLanguageKeywords.getKeywordOrIdentifierType(getText());}
;

Make ReSharper reformat code according to StyleCop rule SA1206: The 'static' keyword must come before the 'other' keyword in the element declaration

I suspect I should create a pattern in ReSharper / Options / Languages / C# / Formatting Style / Type Membership Layout for this. I am currently using the default pattern and I would like some help from someone who is good at them.
I want this to be WRONG:
public new static Age Empty {
get {
return empty;
}
set {
empty = value;
}
}
And this to be right:
public static new Age Empty {
get {
return empty;
}
set {
empty = value;
}
}
In other words, I want static to come before other keywords, like new. Currently ReSharper 5.1 does it the "wrong" way.
ReSharper now has the possibility to configure the arrangement of modifiers.
Open the ReSharper options and go to Code Editing | C# | Code Style. In the Modifiers section Modifiers order you can reorder the arrangement according to your needs (see ReSharper online help: Arranging Modifiers).
To satisfy StyleCop's rule SA1206 move the static modifier above the new modifier:
It is impossible.

Resources