Different cases for "Couldn't resolve reference" in Xtext, particularly solved, but how about an attribute reference? - reference

I have the following Xtext grammar part:
AssignmentStatement: (variable=[SymbolicVariable] | array=ArrayVariable) ':=' value=Expression;
ArrayVariable: varName=[SymbolicVariable] '[' index=Expression ']';
SymbolicVariable: name=ID;
and a test where id1 and id2 are SymbolicVariable, moreover SymbolicVariable can be part of Expression:
id1 := 0 < id2 [ 0 ]
In the test, id1 and id2 are not defined before since I am generating inputs as tests by the grammar and do not care on semantics. I want to create objects for them dynamically to get rid of:
ERROR:Couldn't resolve reference to SymbolicVariable 'id1'.
ERROR:Couldn't resolve reference to SymbolicVariable 'id2'.
while validation.
Following the ideas from post XText cross-reference to an non-DSL resource, I was able to create a ScopeProvider impl as well as a Scope impl:
class MyScope extends AbstractPoSTScopeProvider {
override getScope(EObject context, EReference reference) {
val res = context.eResource
var uri = res.URI
val rs = res.resourceSet
val scope = super.getScope(context, reference)
if (context instanceof ArrayVariableImpl) new ScopeWrapper(scope, res) else scope
}
}
class ScopeWrapper implements IScope {
IScope scope;
Resource resource;
protected new(IScope w, Resource res) {
scope = w
resource = res
}
override getSingleElement(QualifiedName name) {
println("[scope]getSingleElement " + name.toString())
val r = scope.getSingleElement(name)
if (r === null) {
val fac = PoSTPackage.eINSTANCE.getPoSTFactory()
var s = fac.createSymbolicVariable()
s.name = name.toString()
println("[!!!!! ] creation")
Main.isChanged = true //to rerun in cause of modification
val ret = new MyDescr(s, name) //just a wrap
resource.contents += s
ret
} else
r
}
}
After this injection, id2 is appeared and I can generate a code with it, but I still get
ERROR:Couldn't resolve reference to SymbolicVariable 'id1'.
and I do not see id1 anywhere during the debug.
Seems, for attributes we need some other magic.
Which pattern should I follow?

In the test, id1 and id2 are not defined before since I am generating inputs as tests by the grammar and do not care on semantics.
If you are generating your textual model id1 := 0 < id2 [ 0 ], I am not sure why you could not generate it as id1; id2; id1 := 0 < id2 [ 0 ] which would probably resolve OK.
If you really want to "create id1 and id2 dynamically", I think you need to customize your IScopeProvider implementation such that when computing the scopes for both references AssignmentStatement.variable and ArrayVariable.varName, if the parent implementation returns an empty scope, then you simply create a SymbolicVariable in memory and provide it in the returned scope.

Related

Smart cast to 'Bitmap!' is impossible, because 'textBitmap' is a local variable that is captured by a changing closure

when ever I build my project I got this error
here is the kotlin class code
var textBitmap: Bitmap? = null
dynamicItem.dynamicText[imageKey]?.let { drawingText ->
dynamicItem.dynamicTextPaint[imageKey]?.let { drawingTextPaint ->
drawTextCache[imageKey]?.let {
textBitmap = it
} ?: kotlin.run {
textBitmap = Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888)
val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
val textCanvas = Canvas(textBitmap)
drawingTextPaint.isAntiAlias = true
val fontMetrics = drawingTextPaint.getFontMetrics();
val top = fontMetrics.top
val bottom = fontMetrics.bottom
val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
textCanvas.drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
drawTextCache.put(imageKey, textBitmap as Bitmap)
}
I couldn't figure out how to fix it
Instead of doing nested let like that, i would prefer to do some guard clause
val drawingText = dynamicItem.dynamicText[imageKey] ?: return // or you could assign an empty string `?: "" `
val drawingTextPaint = dynamicItem.dynamicTextPaint[imageKey] ?: return
val textBitmap: Bitmap = drawTextCache[imageKey] ?: Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888).applyCanvas {
val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
val fontMetrics = drawingTextPaint.getFontMetrics()
val top = fontMetrics.top
val bottom = fontMetrics.bottom
val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
drawingTextPaint.isAntiAlias = true
drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
}
drawTextCache.put(imageKey, textBitmap)
Basically Kotlin can't smart cast textBitmap to a non-null Bitmap inside that lambda. You're probably getting the error on the Canvas(textBitmap) call, which can't take a null parameter, and the compiler can't guarantee textBitmap isn't null at that moment.
It's a limitation of lambdas referencing external vars which can be changed - I think it's because a lambda could potentially be run at some other time, so no guarantees can be made about what's happening to that external variable and whether something else could have modified it. I don't know the details, there's some chat here if you like.
The fix is pretty easy though, if all you're doing is creating a textBitmap variable and assigning something to it:
// Assign it as a result of the expression - no need to create a var first and keep
// changing the value, no need for a temporary null value, it can just be a val
val textBitmap: Bitmap? =
dynamicItem.dynamicText[imageKey]?.let { drawingText ->
dynamicItem.dynamicTextPaint[imageKey]?.let { drawingTextPaint ->
drawTextCache[imageKey]
?: Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888).apply {
val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
val textCanvas = Canvas(this)
drawingTextPaint.isAntiAlias = true
val fontMetrics = drawingTextPaint.getFontMetrics();
val top = fontMetrics.top
val bottom = fontMetrics.bottom
val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
textCanvas.drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
drawTextCache.put(imageKey, this)
}
}
}
I'd recommend breaking the bitmap creation part out into its own function for readability, and personally I'd avoid the nested lets (because it's not immediately obvious what you get in what situation) but that's a style choice

Why does the mutable StringBuilder behave like the immutable string when a reference is changed?

The "C# 4.0 IN A NUTSHELL" 4th edition book by the Albaharis states on page 249:
". . . calling object.ReferenceEquals guarantees normal referential equality."
So, I decided to test this out.
First I tried value types like this.
int aa1 = 5;
int aa2 = aa1;
MessageBox.Show("object.ReferenceEquals(aa1,aa2) is: " + object.ReferenceEquals(aa1, aa2));
And just as I expected, the result was false:
object.ReferenceEquals(aa1, aa2) is: False
Life was good.
Then I tried a mutable reference type like this.
System.Text.StringBuilder sblr1 = new System.Text.StringBuilder();
sblr1.Append("aaa");
System.Text.StringBuilder sblr2 = sblr1;
MessageBox.Show("object.ReferenceEquals(sblr1,sblr2) is: " + object.ReferenceEquals(sblr1, sblr2));
And just as I expected, the result was true
object.ReferenceEquals(sblr1, sblr2) is: True
Life was still good.
Then I figured that since it is a mutable reference type, then if I change one variable to null, then both should be null.
So I tried the following.
System.Text.StringBuilder sblr1 = new System.Text.StringBuilder();
sblr1.Append("aaa");
System.Text.StringBuilder sblr2 = sblr1;
sblr1 = null;
MessageBox.Show("object.ReferenceEquals(sblr1,sblr2) is: " + object.ReferenceEquals(sblr1, sblr2));
And I expected them to both be null.
But the result I got was False:
object.ReferenceEquals(sblr1, sblr2) is: False
Now life was not so good.
I thought that if it overrode the memory location of sblr1, then it would be overriding the memory location of sblr2 also.
Then I thought that maybe they were pointing to two different nulls, so I tried this:
System.Text.StringBuilder sblr1 = new System.Text.StringBuilder();
sblr1.Append("aaa");
System.Text.StringBuilder sblr2 = sblr1;
sblr2 = null;
MessageBox.Show("sblr1 == " + sblr1 + " and sblr2 == " + sblr2);
But here, only one was pointing to a null like this.
sblr1 == aaa and sblr2 ==
Only one was null.
It was displaying the behavior I'd expect from an immutable reference type like a string object.
With a string object, I can do something like this:
string aa1 = "aaX";
string aa2 = "aaX";
MessageBox.Show("object.ReferenceEquals(aa1,aa2) is: " + object.ReferenceEquals(aa1, aa2));
And they will both reference the same thing like this.
object.ReferenceEquals(aa1, aa2) is: True
because "aaX" only gets written to the assembly once.
But if I do this:
string aa1 = "aaX";
string aa2 = "aaX";
aa1 = null;
MessageBox.Show("After aa1 is null(" + aa1 + "), then aa2 is: " + aa2);
Then they point to different things like this:
After aa1 is null (), then aa2 is: aaX
That's because string objects are immutable. The memory location doesn't get overriden. Rather, the variable points to a different location in Heap memory where the new value exists.
Changing aa1 to null in the above example means that aa1 will point to a different location on the Heap memory.
Why then is the mutable reference type behaving just the same as the immutable reference type?
Edit 4:03PM and 4:08
I've recently tried this:
System.Text.StringBuilder sblr1 = new System.Text.StringBuilder();
sblr1.Append("aaa");
// sblr1 and sblr2 should now both point to the same location on the Heap that has "aaa".
System.Text.StringBuilder sblr2 = sblr1;
System.Text.StringBuilder sblr3 = new System.Text.StringBuilder();
sblr3.Append("bbb");
sblr1 = sblr3;
MessageBox.Show("sblr1 == " + sblr1 + " and sblr2 == " + sblr2 + " and sblr3 == " + sblr3);
Which gave me:
sblr1 == bbb and sblr2 == aaa and sblr3 == bbb
That's more like the result I was expecting.
I see now, thanks to the comments, that I abscent mindedly expected null to act like a memory location.
I thought that if it overrode the memory location of sblr1, then it would be overriding the memory location of sblr2 also.
This is your misunderstanding.
When you write this:
System.Text.StringBuilder sblr2 = sblr1;
You're assigning the sblr2 variable to be a reference to the same instance of StringBuilder as the one pointed to by sblr1. The two variables now point to the same reference.
You then write:
sblr1 = null;
This changes the sblr1 variable to now be a null reference. You didn't change the instance in memory at all.
This has nothing to do with whether the reference is a mutable type or not. You're changing the variables, not the instance which they are referencing.
As for your string example:
That's because string objects are immutable. The memory location doesn't get overridden
This actually is not true. The fact that you're setting one string variable to null doesn't really have anything to do with the string being immutable. That's a separate concern.
Why then is the mutable reference type behaving just the same as the immutable reference type?
The behavior you're seeing has nothing to do with mutability. It is the standard behavior for all reference types (whether immutable or mutable). Mutability is a different issue.
The main issue with mutability is this:
Suppose you have a class, like so:
class Foo
{
public int Bar { get; set; }
}
If you write this:
Foo a = new Foo();
a.Bar = 42;
Foo b = a;
b.Bar = 54;
Console.WriteLine(a.Bar); // Will print 54, since you've changed the same mutable object
With immutable types, this can't happen, since you can't change Bar - instead, if you make an immutable class:
class Baz
{
public Baz(int bar) { this.Bar = bar; }
public int Bar { get; private set; }
}
You would need to write:
Baz a = new Baz(42);
Baz b = a;
// This isn't legal now:
// b.Bar = 54;
// So you'd write:
b = new Baz(54); // Creates a new reference
Alternatively, you could make the class return a new reference on a "change" operation, ie:
class Baz
{
public Baz(int bar) { this.Bar = bar; }
public int Bar { get; private set; }
public Baz Alter(int newValue) { return new Baz(newValue); } // May copy other data from "this"
}
Then when you'd write:
Baz a = new Baz(42);
Baz b = a.Alter(54); // b is now a new instance
This is what happens with string - all of the methods return a new instance, since a string is immutable, so you can never "change" the existing copy.
This has nothing to do with mutability. The rules involved here are the same for all reference types. A non-ref non-out variable (or member, or slot in a collection) of a reference type is a reference (duh). That means it refers to some object. It does not refer to another reference, or to a location where another reference is (e.g. to a variable). When you assign to a variable (or member, or slot in a collection), you change what reference is in that place; you do not overwrite any part of any object (except, of course, the member you assign to, if it's a member).
In your code, there are two variables srbl1 and srbl2, each of which stores a reference to the same string builder object. Assigning to either changes overwrites one of those reference (e.g. with null, or with a reference to a different object).
Changing a reference is just changing what something refers to. It doesn't change the object itself.
One way to look at it is to imagine an array of integers:
int[] foo = new int[] {0, 1, 2, 3, 4, 5};
You can create two indexes that refer to items in the array:
int ix = 1;
int iy = ix;
And then foo[ix] == foo[iy].
If you then write foo[ix] = 42, then foo[ix] == foo[iy] is still true because you changed the value that the indexes referred to.
But if you change the index so that ix = 3, then ix and iy are referring to different things.
Reference types work exactly the same way.
When you write sblr1 = new StringBuilder(), you've created a new StringBuilder object instance and made sblr1 point to it. If you then write sblr2 = sblr1, you're just making sblr2 point to the same thing. And then sblr1 = null just says, "sblr1 isn't pointing to anything anymore." It doesn't actually affect the item it refers to, just as changing the index to an array doesn't affect the value of the item being indexed.

How do I use groovy's AS keyword

This may be a duplicate but "as" is an INCREDABLY hard keyword to google, even S.O. ignores "as" as part of query.
So I'm wondering how to implement a class that supports "as" reflexively. For an example class:
class X {
private val
public X(def v) {
val=v
}
public asType(Class c) {
if (c == Integer.class)
return val as Integer
if(c == String.class)
return val as String
}
}
This allows something like:
new X(3) as String
to work, but doesn't help with:
3 as X
I probably have to attach/modify the "asType" on String and Integer somehow, but I feel any changes like this should be confined to the "X" class... Can the X class either implement a method like:
X fromObject(object)
or somehow modify the String/Integer class from within X. This seems tough since it won't execute any code in X until X is actually used... what if my first usage of X is "3 as X", will X get a chance to override Integer's asType before Groovy tries to call is?
As you say, it's not going to be easy to change the asType method for Integer to accept X as a new type of transformation (especially without destroying the existing functionality).
The best I can think of is to do:
Integer.metaClass.toX = { -> new X( delegate ) }
And then you can call:
3.toX()
I can't think how 3 as X could be done -- as you say, the other way; new X('3') as Integer is relatively easy.
Actually, you can do this:
// Get a handle on the old `asType` method for Integer
def oldAsType = Integer.metaClass.getMetaMethod( "asType", [Class] as Class[] )
// Then write our own
Integer.metaClass.asType = { Class c ->
if( c == X ) {
new X( delegate )
}
else {
// if it's not an X, call the original
oldAsType.invoke( delegate, c )
}
}
3 as X
This keeps the functionality out of the Integer type, and minimizes scope of the effect (which is good or bad depending on what you're looking for).
This category will apply asType from the Integer side.
class IntegerCategory {
static Object asType(Integer inty, Class c) {
if(c == X) return new X(inty)
else return inty.asType(c)
}
}
use (IntegerCategory) {
(3 as X) instanceof X
}

In order for a groovy closure to modify a variable defined in the scope of a delegate, do you need to explicitly specify delegate.theVariableName?

I stumbled onto something with Groovy closures and delegates that I'm not sure is an official part of the language or perhaps even a bug.
Basically I am defining a closure that I read in as a string from an external source,
and one of the variables in the class that defines the closure needs to be modified by the closure. I wrote
a simple example showing what I found works, and what does not work.
If you look at the test code below you will see a class that defines a variable
animal = "cat"
and two closures defined on the fly from strings that attempt to modify the animal variable.
This works >
String code = "{ -> delegate.animal = 'bear'; return name + 'xx' ; }"
But this does not
String code = "{ -> animal = 'bear'; return name + 'xx' ; }"
It seems like I need to explicitly qualify my to-be-modified variable with 'delegate.' for this to work.
(I guess i can also define a setter in the enclosing class for the closure to call to modify the value.)
So.... I've found out how to make this work, but I'd be interested if someone could point me to some groovy
doc that explains the rules behind this.
Specifically.... why will the simple assignment
animal = 'bear'
affect the original variable ? Are there shadow copies being made here or something ?
import org.junit.Test
/*
* Author: cbedford
* Date: 8/30/12
* Time: 1:16 PM
*/
class GroovyTest {
String animal = "cat"
String name = "fred"
#Test
public void testDelegateWithModificationOfDelegateVariable() {
String code = "{ -> delegate.animal = 'bear'; return name + 'xx' ; }"
def shell = new GroovyShell()
def closure = shell.evaluate(code)
closure.delegate = this
def result = closure()
println "result is $result"
println "animal is $animal"
assert animal == 'bear'
assert result == 'fredxx'
}
// This test will FAIL.
#Test
public void testDelegateWithFailedModificationOfDelegateVariable() {
String code = "{ -> animal = 'bear'; return name + 'xx' ; }"
def shell = new GroovyShell()
def closure = shell.evaluate(code)
closure.delegate = this
def result = closure()
println "result is $result"
println "animal is $animal"
assert animal == 'bear'
assert result == 'fredxx'
}
}
Groovy closures have five strategies for resolving symbols inside closures:
OWNER_FIRST: the owner (where the closure is defined) is checked first, then the delegate
OWNER_ONLY: the owner is checked, the delegate is only checked if referenced explicitly
DELEGATE_FIRST: the delegate is checked first, then the owner
DELEGATE_ONLY: the delegate is checked first, the owner is only checked if referenced explicitly
TO_SELF: neither delegate nor owner are checked
The default is OWNER_FIRST. Since the closure is defined dynamically, your owner is a Script object which has special rules itself. Writing animal = 'bear' in a Script will actually create a new binding called animal and assign 'bear' to it.
You can fix your tests to work without explicitly referencing delegate by simply changing the resolve strategy on the closure before calling it with:
closure.resolveStrategy = Closure.DELEGATE_FIRST
This will avoid the odd the Script binding and use the delegate as expected.

Given a collection object, would like to assign to a local variable of specific type

I'd like to recover type information using reflection. I have
public Foo(object coll, string tValue)
{
var x = col1 as IList;
if (x != null)
x.Action();
var y = col1 as IDictionary;
if (y != null)
y.Action();
}
But would like to have
public Foo(object coll, string tValue)
{
var x = col1 as IList<TValue>;
if (x != null)
x.Action();
var y = col1 as IDictionary<int, TValue>;
if (y != null)
y.Action();
}
Is it possible to arrive at and use generic interfaces instead of the old-school non-generic collection interfaces, given only the contained class name?
Once the local variable type is established, I'd like to avoid paying the reflection and dynamic invocation penalties when looping over the collection.
Another example, maybe clearer:
var list = new Dictionary<int, MyObject>();
list.Add(100, new MyObject());
object listObject = list;
var x = listObject as IDictionary<int, dynamic>;
if (x != null)
{
foreach (var entry in x)
{
Console.WriteLine(entry.Key);
Console.WriteLine(entry.Value);
}
}
x is null...
I'm not sure if you intend to call a method on generic collection for every item in the collection or if you just want the values from the generic collection.
For your third block of code, you could continue to use the non-generic interface and use an enumerator.
var x = listObject as IDictionary;
if (x != null)
{
var en = x.GetEnumerator();
while(en.MoveNext())
{
Console.WriteLine(en.Key);
Console.WriteLine(en.Value);
}
}
If you intend to call a method without knowing the exact generic types for the generic IList or IDictionary, then you'll have to use MethodInfo.Invoke. Cache the MethodInfo outside of the loop for a small performance boost.
CreateDelegate would be faster, but you'll need to know the exact generic types. You could get around that with expression trees, but the amount of code to maintain might not be worth the performance gain. Check out MagicMethod in Jon Skeets article
Making reflection fly and exploring delegates

Resources