when to use cross-reference and when use containment reference? - dsl

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.

Related

Using Roslyn, if I have an IdentifierNameSyntax, can I find the member type it refers to (field, property, method...)

I am attempting to use the Roslyn SDK and StackExchange.Precompilation (thank you!) to implement aspect-oriented programming in C#6. My specific problem right now is, starting with an IdentifierNameSyntax instance, I want to find the "member type" (method, property, field, var, etc.) that the identifier refers to. (How) can this be done?
Background:
The first proof-of-concept I am working on is some good old design-by-contract. I have a NonNullAttribute which can be applied to parameters, properties, or method return values. Along with the attribute there is a class implementing the StackExchange.Precompilation.ICompileModule interface, which on compilation will insert null checks on the marked parameters or return values.
This is the same idea as PostSharp's NonNullAttribute, but the transformation is being done on one of Roslyn's syntax trees, not on an already compiled assembly. It is also similar to Code Contracts, but with a declarative attribute approach, and again operating on syntax trees not IL.
For example, this source code:
[return: NonNull]
public string Capitalize([NonNull] string text) {
return text.ToUpper();
}
will be transformed into this during precompilation:
[return: NonNull]
public string Capitalize([NonNull] string text) {
if (Object.Equals(text, null))
throw new ArgumentNullException(nameof(text));
var result = text.ToUpper();
if (Object.Equals(result, null))
throw new PostconditionFailedException("Result cannot be null.");
return result;
}
(PostconditionFailedException is a custom exception I made to compliment ArgumentException for return values. If there is already something like this in the framework please let me know.)
For properties with this attribute, there would be a similar transformation, but with preconditions and postconditions implemented separately in the set and get accessors, respectively.
The specific reason I need to find the "member type" of an identifier here is for an optimization on implementing postconditions. Note in the post-compilation sample above, the value that would have been returned is stored in a local variable, checked, and then the local is returned. This storage is necessary for transforming return statements that evaluate a method or complex expression, but if the returned expression is just a field or local variable reference, creating that temporary storage local is wasteful.
So, when the return statement is being scanned, I first check if the statement is of the form ReturnKeyword-IdentifierSyntaxToken-SemicolonToken. If so, I then need to check what that identifier refers to, so I avoid that local variable allocation if the referent is a field or var.
Update
For more context, check out the project this is in reference to on GitHub.
You'll need to use SemanticModel.GetSymbolInfo to determine the symbol an identifier binds to.
Use SemanticModel.GetTypeInfo.Type to obtain the TypeInfo and use it to explore the Type

Object reference exactly

Demo demo=new Demo();
Here demo is a reference variable. Are reference variables equal to object references... ?
If no then please explain the concept of object reference.
Demo represents the type of the object.
demo represents the object reference, you will be able to refer to new Demo() object and calling its methods (for example).
new Demo() represents the object itself which is situated in heap memory.
In case of java language,
When you write the statement
Demo obj = new Demo();
It means that You are declaring a variable named obj and it is of type Demo.
by writing
obj = new Demo();
You are creating a new object in the heap memory and the reference variable "obj" will refer to it so that when you want to access the object created just now, you can access it through reference variable "obj".
so when you want to call some method on Demo object, you can call it using
obj.someMethod();
A reference to an object is a way to denote that object. The address of an object, for example, is one kind of reference (probably the simplest kind). Other kinds of references can exist, too, and they are written and read using some more complicated logic. It could theoretically be a double pointer, a pseudo-address, or something else - as long as it contains enough information that (if interpreted in a specified way) can be used to denote a specific object, .
A reference variable is a variable whose value is a reference to an object. So, for example, a reference variable could be a variable whose value is the address of an object, or (as I described above) something different, but equivalent.
For comparison, the other common type of variable (called primitive type in Java, value type in C# and other names in other contexts) is the kind variable whose value is an actual object (instead of a reference).

Why assign a reference to a struct in go?

I'm having a look at the code at this page:
http://golang.org/pkg/net/http/
And there's one thing I don't understand - at some point, a new structure is created and initialized like this:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
Why use & when creating this structure?
I've also read this blog post and structs are initialized like this:
r := Rectangle{}
What is the difference between both and how should I know which one to use?
The difference is in the type of your variable.
client := &http.Client{
makes client of type *http.Client
while
client := http.Client{
builds a http.Client.
The top one is returning a pointer. It is a Go idiom instead of using new. The second one is just a value object. If you need a pointer use the top.
Check the effective go doc for more about this
http://golang.org/doc/effective_go.html#allocation_new
In object-oriented programming, in order for an object to have dynamic lifetime (i.e. not tied to the current function call), it needs to be dynamically allocated in a place other than the current stack frame, thus you manipulate the object through a pointer. This is such a common pattern that in many object-oriented languages, including Java, Python, Ruby, Objective-C, Smalltalk, JavaScript, and others, you can only deal with pointers to objects, never with an "object as a value" itself. (Some languages though, like C++, do allow you to have "objects as values"; it comes with the RAII idiom which adds some complexity.)
Go is not an object-oriented language, but its ability to define custom types and define methods that operates on that custom type, can be made to work very much like classes and methods. Returning a pointer to the type from the "constructor" function allows the "object" to have a dynamic lifetime.
When we use reference, we use a single item throughout the program runtime. Even if we assign that to a new variable or pass through a function. But when we use value, we make new copies of individual items.
( Reference is not right word according to golang convention. "Address of value" would be more appropriate here https://golang.org/ref/spec#Package_initialization )
An example will make it much clear I hope.
type Employee struct {
ID int
Name string
Address string
}
func main() {
andy := &Employee{}
andy.Name = "Andy"
brad := andy
brad.Name = "Brad"
fmt.Println(andy.Name)
}
The result of this code block would be:
Brad
As we made new variable from it but still referring to same data. But if we use value instead of reference and keep the rest of the code same.
// from
andy := &Employee{}
// to
andy := Employee{}
This time the result would be:
Andy
As this time they both are individual items and not referring to same data anymore.

Is it possible to take the name of a variable and turn it into a string in ActionScript 3.0?

I am making a simple debugger window in ActionScript for myself where I can add and remove variables I want to track. I was to be able to add variables to the list by just doing something like
DebuggerMonitor.trackVar(variable).
My question is, is there any way I can turn "variable" itself (the name, not the value) into a String to be added into a text field?
Depending on how "intelligent" your debugger should be, you could just pass the name along:
DebuggerMonitor.trackVar( variable, "variable" );
since obviously, when used in a context like this, the name should be known at the time you are writing the program.
You can also do some reflection magic to get instance variable names, but it won't work for temp variables (their names are dropped at compilation time):
public function getVariableName( instance:*, match:* ):String {
var typeDescription:XML = describeType( instance );
var variables:XMLList = typeDescription..variable;
var accessors:XMLList = typeDescription..accessor;
for each(var variable:XML in variables)
if(matchesXMLName( instance, variable, match ))
return variable.#name;
for each(var accessor:XML in accessors)
if(matchesXMLName( instance, accessor, match ))
return accessor.#name;
return "No name found.";
}
private function matchesXMLName( instance:*, xml:XML, match:* ):Boolean {
return match == instance[xml.#name.toString()];
}
var varName:String = getVariableName ( myObject, variable );
Using reflections like this will also be quite costly, if used often - you will have to think of a way to cache the type descriptions.
I recommend you check out the as3commons reflections package - there is a lot of useful functionality in there...
Short answer - No :(
You can access the type name but not individual instance names, as these are lost at run-time.
There is a confusion caused by the keyword 'var' because it is used to create several types of bindings.
Lexical bindings (the keyword 'var' was used inside a function).
Dynamic bindings (the keyword 'var' was used to declare a class' field).
Lexical bindings are interpreted by the compiler at compile time as addresses of the registers of the registers space occupied by the function. The names given to lexical bindings perish at this time and it is not possible to restore them at runtime - therefore you can't get the "name" of the variable.
Dynamic bindings are a kind of "public API" of the objects that declare them, they may be accessed from the code that was not compiled together with the code that created them, this is why, for the purpose of reflection the names of these bindings are stored in compiled code. However, ActionScript has no way of referencing LHS values, so you cannot, even if you know the name of the variable and the object declaring it, pass it to another function. But you can look it up in the debugger or by calling describeType on the object declaring the variable. Note that describeType will not show information on private variables even if you are calling it from the scope of the object in question.

How to determine whether a dependency object implements a given dependency property (C# / WPF)

I am working with the classes in the System.Windows.Documents namespace, trying to write some generic code that will conditionally set the value of certain dependency properties, depending on whether these properties exist on a given class.
For example, the following method assigns an arbitrary value to the Padding property of the passed FrameworkContentElement:
void SetElementPadding(FrameworkContentElement element)
{
element.SetValue(Block.PaddingProperty, new Thickness(155d));
}
However, not all concrete implementations of FrameworkContentElement have a Padding property (Paragraph does but Span does not) so I would expect the property assignment to succeed for types that implement this property and to be silently ignored for types that do not.
But it seems that the above property assignment succeeds for instances of all derivatives of FrameworkContentElement, regardless of whether they implement the Padding property. I make this assumption because I have always been able to read back the assigned value.
I assume there is some flaw in the way I am assigning property values. What should I do to ensure that a given dependency property assignment is ignored by classes that do not implement that property?
Many thanks for your advice.
Tim
All classes that derive from Block have the Padding property. You may use the following modification:
void SetElementPadding(FrameworkContentElement element)
{
var block = element as Block;
if (block == null) return;
block.Padding = new Thickness(155d);
}
Even without this modification everything would still work for you because all you want is for Padding to be ignored by classes that do not support it. This is exactly what would happen. The fact that you can read out the value of a Padding dependency property on an instance that does not support it is probably by design but you shouldn't care. Block and derivatives would honor the value and all others would ignore it.

Resources