My xtext grammar constrains a hierarchical structure. When the scope of an element in the hierarchical needs to be computed the following must be done:
get a list of element with the type A
get a list of element with the type B
add the two list to the scope. Repeat the for the parent element and add the parents scope to the current scope.
I use
scope_a = Scopes.scopeFor(list_a)
scope_b = Scopes.scopeFor(list_b, scope_a)
but get stuck when adding the parents scope to scope_b to create the final scope.
the scopeFor methods are just helpers. have a look at their code. they call
org.eclipse.xtext.scoping.Scopes.scopeFor(Iterable<? extends T>, Function<T, QualifiedName>, IScope)
which allows to pass a parent scope
Related
I saw this construction in rationals.jl, and I am trying to understand it. I can write
struct Bar
y
global func(x) = new(x)
end
Then if I try:
a = Bar()
I get an error. It is like func is now an inner constructor. And I can actually use it by writing:
a = func(2)
If I remove the keyword global, I can't use this inner constructor anymore. What is going on? Why is global there, and could I use the inner constructor somehow without it (perhaps by qualifying the name)?
How can the inner constructor have a different name than the struct itself? What, in fact, is an inner constructor?
TL/DR
An inner constructor is a method of the struct type (i.e., (::Type{Bar})(...) which has access to new. You can put arbitrary method definitions inside a struct -- there is no technical requirement to only have inner constructors -- but this is only useful in rare cases.
Long version
This is a rare case that the manual doesn't even cover explicitely (and I long didn't know was legal at all). In my understanding, two rules apply:
Inside the struct definition, and only there, you are allowed to use new.
If any inner constructor method is defined, no default constructor method is provided: it is presumed that you have supplied yourself with all the inner constructors you need.
However, nothing requires the inner constructor to be a method of the struct type! Instead you may actually define arbitrary methods.
And then, scoping applies. With a "regular" inner constructor, what you get is a method for Type{Bar}. This requires no global, as the type is present in outer scope.
In your case, without the global, func is local and so there is no constructor accessible at all outside the struct definition. This makes little sense. The global function definition is something that can be useful in rare cases when you want to prevent direct construction of values of you type, but only allow conversion. I have seen this kind of pattern:
struct Baz
Base.reinterpret(::Type{Baz}, ...) = new(...)
end
This adds a (globally available) method to reinterpret, the only entry point to constructing Bazes. Putting it inside the struct is necessary, as at some place you need to create the object and thus require access to new.
What is the point of ParserRuleContext's this method
<T extends ParserRuleContext> List<T>
T getRuleContext(Class<? extends T> ctxType)
When I try to get a child context of a parent using this method it always returns null.
for example
parentRuleContext.getRuleContext(ChildOneContext.class,MyParser.Rule_ChildOne)
this I assume should return all ChildOneContexts but always returning null.
Am I wrongly using this method and its purpose is something different? Since there is no documentation on this, not clear about the use.
getRuleContext is supposed to return the ith child (from the variant with the i parameter) or all children of a given class type. If you get back null I'd say you don't have a child of the given type. You can easily check this by examining the children member and see if a ChildOneContext child exists.
I need to implement a domain specific language. I have a panel and some shapes on it.
'panel' name = ID '(' title = STRING',' bgcolor = Color',' width = INT',' height = INT ')''{'((rects += Rect)| (ellipse += Ellipse)|(arcs += Arc)|)*'}'
and each shape has a unique rule with some other features. for example:
RoundRect:
'roundrectangle' name = ID '{'
(fill ?= 'filled' (fillpattern?='fillpattern' fillpaint=Paint)?)?
(stroke?='stroke' str=Stroke)?
'paint' paint=Paint
'coordination' x=INT ',' y=INT
'dimention' height=INT ',' width=INT
'arc' archeight=INT ',' arcwidth=INT
'}'
as it obvious in this DSL, I used some references. But I don't know this rules is correct or I should use cross-reference in those?
This rule works fine and I receive the correct output that I expected. But I know when a feature is not of the basic type (string, integer, and so on), it is
actually a reference (an instance of EReference),this is a containment reference, although for non-containment references, the referenced object is stored somewhere else,
for example, in another object of the same resource or even in a different resource.
And point is that a cross-reference is implemented as a non-containment reference.
I need to know when I should use cross-reference and when use containment reference?
As far as I know the difference is as following:
A containment-reference is if you want to reference to the content of a rule so it's just lazy for redefining the rule's content everytime you use the containment-reference.
A cross-reference behaves a bit different: If you use a cross-reference the parser need the user having typed in content of the rule the cross-reference refers to beforeallowing him to refer to that already typed in content.
An example would be a real programming language: A Method call would be a cross-reference as the method of this name should already be declared somewhere in the code because otherwise it doesn't exist. In contrary the normal code would be implemented as a containment-reference as it can be used (for example) within a class, a field or a method and the code you are typing in just needs to fullfill the existance of a few keywords and structures but these are only defined in the parser itself and needn't be defined by the user himself before beeing able to use them.
I hope I have illustrated it well enough so you now know about the difference and the meaning of these reference types.
Greeting Krzmbrzl
Your grammar describes the AST of your language. Therefore, a meta model is derived from your grammar. To describe references between your AST elements you can use containmend references and cross references. A containment reference is used if you want to describe a parent-child relation where the child object is "created" / declared during the parent object is created. A cross reference is used if the parent object points to a child object which is created / declared in an other parent object. To "draw a picture": A containment reference is a top -> bottom reference and a cross reference is a left -> right reference.
For example assume you have a field (private int field = 42;) or method (public void foo() {...}) declaration of a Java class. This declaration is modeled with a containment reference, because a Java class contains field and method declarations. On the other you have a statement field++; within the method body of foo(). There you use the former declared field foo and it is modeled as a cross reference.
In general I would say: Any declaration is modeled as a containment reference and any usage of an already declared whatever is modeled as a cross reference.
I am not sure whether this is the right forum to ask this question, but it refers to code, so I am asking here.
In the book "Groovy in action", section 7.1.4 (named parameters), the author says that usage of named params "crops up frequently in creating immutable classes that have some parameters that are optional".
What has immutability of the class got to do with optional parameters? I thought these 2 topics were completely orthogonal.
crops up frequently in creating immutable classes that have some parameters that are optional
the sentence above is a bit blurry as there is no such thing as "class parameters", i can only assume it relates to method/constructor parameters.
when we're talking about constructors, Groovy's named parameters make sense when its about optional parameters:
#groovy.transform.Immutable
class Person {
String firstName
String lastName
Integer age
}
def p = new Person(age: 42, lastName: 'Doe')
The above example shows how to create an immutable Person instance. The firstName is not provided as named parameter, it's optional. In fact, with named parameters it's possible to specify any parameter combo when making the constructor call without actually having to implement constructors for all combinations.
There is also the possibility of using named parameters in instance/static method calls, as shown in this blog post by Mr. Haki.
The key to that statement is that if you're dealing with an immutable class, the implication is that you have only one chance to set state - in a constructor. Normally you'd be able to manipulate an (mutable) object via setters, one-at-a-time, to build up the desired state. For an immutable, you'd have to create a ctor for every possible set of instantiation states instead, if a facility like optional params were not available. For a class with many fields, this could get messy.
The following example is adapted from 'Groovy in Action'
class Mother {
Closure birth() {
def closure = { caller ->
[this, caller]
}
return closure
}
}
Mother julia = new Mother()
closure = julia.birth()
context = closure.call(this)
println context[0].class.name // Will print the name of the Script class
assert context[1] instanceof Script
According to the book, the value of this inside the closure is the outermost scope (i.e. the scope in which julia is declared). Am I right in assuming that
this inside a closure evaluates to the scope in which the closure is called?
within the closure shown above, this and caller refer to the same scope?
Thanks,
Don
"this" in a block mean in Groovy always (be it a normal Java-like block or a Closure) the surrounding class (instance). "owner" is a property of the Closure and points to the embedding object, which is either a class (instance), and then then same as "this", or another Closure. I would forget about the scope thing totally for this part. So in the case above it is correct, that "this" refers to a mother.
And now to make things complicated... "this" and the implicit this are not the same in Groovy. So if you have a Closure {foo()} and {this.foo()} you can get differing results. this.foo() will always be resolved to the embedding class, while only foo() will be resolved using the Groovy meta object protocol (MOP) and can point to something entirely different. A builder may for example set a delegate on that Closure and catch the method invocation, for a Groovy builder that is standard. Anyway... that is why this part is called dynamic scoping.
Historic background:
Before Groovy 1.0 "this" was the Closure object itself. But was changed because actually calling this.foo() became impossible if a builder did capture all calls. then you had no way to call local methods from within the builder anymore. There was a lot of tries with changing the standard resolve strategy - and big emotional discussions too. But in the end, changing "this" to refer to the embedding class was a simple solution to the problem and is more in line with people coming from Java plus it let's you easily bypass the MOP if you insist.
Take a look at page 144
...this refers to the closure, not to
the declaring object. At this point,
closures play a trick for us. They
delegate all method calls to a
so-called delegate object, which by
default happends to be the declaring
object (that is, the owner). This make
the closure appear as if the enclosed
code runs in the birthday context.
For your questions;
this inside a closure evaluates to the scope in which the closure is called?
from the book they state that "this refer to the closure, not to the declaring object"
But from bertport and my experiment, it seems "this" is actually the declaring object.
Either ways, the answer is still "no" for your question.
within the closure shown above, this and caller refer to the same scope?
I'm afraid not.
Be aware that page 143 and 144 in Groovy in Action need some corrections
http://groovy.canoo.com/errata/erratum/show/5
http://groovy.canoo.com/errata/erratum/show/8
{
def self = ({ owner })()
}
owner: the enclosing object (this or a surrounding Closure).
Sake says, "this is the closure not the object where the closure [is] constructed." But when we run this script, we find that this is a Mother, not a Closure.