Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Linking/Scoping/Shadowing issues in augmented SmallJava((Apologies to Mr. Bettini))
Linking/Scoping/Shadowing issues in augmented SmallJava [message #1603262] Fri, 06 February 2015 03:53 Go to next message
Jordan Wallet is currently offline Jordan WalletFriend
Messages: 16
Registered: December 2013
Junior Member
Having done a run of building SmallJava from Lorenzo Bettini's book, I'm trying to reinforce and strengthen my understanding by doing it again from scratch with some augmentation (and a different name, to keep everything tidy). The biggest headache so far has been adding member access that doesn't require an object prefix.

First I should note that I have made (or attempted to make) the language case-insensitive by the following in the workflow:
// The antlr parser generator fragment.
			fragment = parser.antlr.ex.rt.AntlrGeneratorFragment auto-inject {
				options = {
					ignoreCase = true
				}
			}

I thought I should mention it since there doesn't seem to be a clear and unequivocal source online indicating that this is the correct way to do it in the most recent version of XText.

For those unfamiliar, the (unmodified) member selection looks like this:
BSSelectionExpression returns BSExpression:
	BSTerminalExpression
	({BSMemberSelection.receiver=current} '.'
	member=[BSMember]
	(methodinvocation?='('
	(args+=BSExpression (',' args+=BSExpression)*)? ')')?)*
;


To get member selections without an explicit "this", the grammar was modified to allow method invocation on terminal symbols:
BSTerminalExpression returns BSExpression:
	...
	{BSSymbolRef} symbol=[BSSymbol] (methodinvocation?='('(args+=BSExpression (',' args+=BSExpression)*)? ')')?


...with members added as symbols:
BSSymbol:
	BSVariableDeclaration | BSParameter | BSMember
;


Although it adds a tiny bit of headache to the validation of BSSymbolRefs, this has so far turned out startlingly well, considering that grammar design seems to involve a lot of Magic. However, now that I'm writing tests involving duplicate names, some kind of hiccup seems to have occurred:
	@Test def void testCrossLinkingWithMemberAsSymbol() {
		'''
		class R { V vv; }
		class P extends R {
			R m() { return null; }
		}
		class N extends R {}
		class V extends R {}
		
		class C extends R {
			R m(P pp) {
				return pp.m().vv;
			}
		}
		'''.parse => [
			assertEquals("V", classes.head.fields.head.type.name); //passes: R's vv is of type V
			assertEquals("R", classes.get(1).methods.head.type.name); //passes: P's m() is of type R
			
			//C.m()'s pp.m().vv is a member of the type returned by pp.m(). We know the member selection m() to be non-null,
			//because the following assertion on its return type passes:
			assertEquals("R", (((classes.last.methods.head.body.statements.head as BSReturn)
				.expression as BSMemberSelection).receiver as BSMemberSelection).member.type.name)
				
			//The pp.m() selection is very definitely pointing to the correct R:
			assertSame(classes.get(0),  (((classes.last.methods.head.body.statements.head as BSReturn)
				.expression as BSMemberSelection).receiver as BSMemberSelection).member.type)
				
			//The type EObject of pp.m().vv should be an object with a toString resembling this:
					//org.xtext.example.blorquescript.blorqueScript.impl.BSClass@00000000 (name: V)
			//but it's actually null; the following assertion fails:
			assertNotNull(((classes.last.methods.head.body.statements.head as BSReturn).expression as BSMemberSelection).member.type)
			//This is because the member itself seems to be "synthetic", which I take to mean,
			//the linker never found R.vv when it was deciding what pp.m().vv was referring to.
			
			assertNoErrors //fails: Couldn't resolve reference to BSMember 'vv' on the BSMemberSelection
		]
	}


I suspect the same issue is to blame for the lack of shadowing:
	@Test def void testVariableShadowsParamLinking() {
		'''
		class C {
			A m(A a) {
				A a = null;
				return a;
			}	
		}
		class A {}
		'''.parse.classes.head.methods.head => [
				System.out.println(body.statements.head.getScope(BlorqueScriptPackage::eINSTANCE.BSSymbolRef_Symbol).allElements.map[name].join(", "))
				returnStatements.last.expression.assertScope(BlorqueScriptPackage::eINSTANCE.BSSymbolRef_Symbol,
					"a, a, m, m.a, m.a, C.m, C.m.a, C.m.a"
					//This was coming up "a, a, m.a, m.a, C.m.a, C.m.a" until I added basic custom scoping as per Bettini p. 242
				)
				body.statements.head.assertSame(
					(returnStatements.last.expression as BSSymbolRef).symbol
					//fails: This symbol should be the declaration, but is instead the parameter.
					//  my custom scoping didn't help even though it passes into scopeFor first the statement and then the parameter,
					//  as in Mr. Bettini's book.
				)
		]
	}


So now I'm left scratching my head and wondering what to do. The answer is generally, "fix your grammar", but it took me quite a lot of trial-and-error just to get this one, and I don't really have an idea on how to refactor it. I also considered trying to mess with the linker, but I haven't been able to find resources for that, which suggests to me that it's probably not the way to go for such a simple problem. With regards to shadowing, I've also considered deleting the parameter out of the scope entirely if another resource with the same name is found, but that seems way too heavy-handed since it might go away on its own when I get cross-referencing fixed.

Any ideas would be greatly appreciated.

[Updated on: Fri, 06 February 2015 04:01]

Report message to a moderator

Re: Linking/Scoping/Shadowing issues in augmented SmallJava [message #1603526 is a reply to message #1603262] Fri, 06 February 2015 08:05 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi,

you did not post your scopeprovider. nor a comlete grammar. (simply adapting smalljava from github does not work)
both would be helpful to analyze.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Linking/Scoping/Shadowing issues in augmented SmallJava [message #1604185 is a reply to message #1603526] Fri, 06 February 2015 17:47 Go to previous messageGo to next message
Jordan Wallet is currently offline Jordan WalletFriend
Messages: 16
Registered: December 2013
Junior Member
Rather than reproduce the whole grammar and clutter this page more, suffice it to say that with the exception of what's already been listed, and the particular string constants used to refer to rules, the grammar is identical to SmallJava.xtext on github except that for now any reference to an "AccessLevel" has been removed:
BSField:
  //This part was deleted: access=SJAccessLevel?
  type=[BSClass|QualifiedName] name=ID ';'
;
BSMethod:
  //This part was deleted: access=SJAccessLevel?
  type=[BSClass|QualifiedName] name=ID
  '(' (params+=BSParameter (',' params+=BSParameter)*)? ')'
  body=BSMethodBody
;

//the rule below was deleted:
enum SJAccessLevel:
PRIVATE='private' | PUBLIC='public' | PROTECTED='protected';

Equivalence is ensured because the file was initially created by replacing strings from the github file linked above.

The scope provider is as Bettini p. 242:
class BlorqueScriptScopeProvider extends AbstractDeclarativeScopeProvider {
	def scope_BSSymbolRef_symbol(BSExpression context, EReference ref) {
		context.symbolsDefinedBefore(context)
	}
	
	def dispatch IScope symbolsDefinedBefore(EObject context, EObject obj) {
		context.eContainer.symbolsDefinedBefore(obj.eContainer)
	}
	
	def dispatch IScope symbolsDefinedBefore(BSMethod context, EObject obj) {
		Scopes::scopeFor(context.params)
	}

	def dispatch IScope symbolsDefinedBefore(BSBlock context, EObject obj) {
		Scopes::scopeFor(
			context.statements.variablesDeclaredBefore(obj),
			context.eContainer.symbolsDefinedBefore(obj.eContainer)
		)
	}
	
	//-- PRIVATE HELPERS --//
	def private variablesDeclaredBefore(List<BSStatement> list, EObject obj) {
		list.subList(0, list.indexOf(obj)).filter(typeof(BSVariableDeclaration))
	}
}

The previously posted test testCrossLinkingWithMemberAsSymbol was created before this scope provider, and the addition of the scope provider had no effect on test results. Effects on scope in testVariableShadowsParamLinking are noted in its comments.
Re: Linking/Scoping/Shadowing issues in augmented SmallJava [message #1604296 is a reply to message #1604185] Fri, 06 February 2015 19:33 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Using small Java and adapting the rules does not work for me
(the already listet part)


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Fri, 06 February 2015 19:45]

Report message to a moderator

Re: Linking/Scoping/Shadowing issues in augmented SmallJava [message #1604334 is a reply to message #1604296] Fri, 06 February 2015 20:06 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
so you should debug the scope provider

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Previous Topic:xtext validation (warning method) information needed
Next Topic:TEXT terminal
Goto Forum:
  


Current Time: Thu Apr 25 07:34:25 GMT 2024

Powered by FUDForum. Page generated in 0.04038 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top