Crossreference to member of aliased container [message #757576] |
Sat, 19 November 2011 19:12 |
Tobias Habermann Messages: 9 Registered: July 2009 |
Junior Member |
|
|
Hello,
I recently started trying out Xtext and I'm now trying to implement a (small) subset of SQLite for a project. I ran into the following problem for SELECT queries (simplified example):
Quote:
Table:
'CREATE' 'TABLE' name=ID '(' columns+=ColumnDef (',' columns+=ColumnDef)* ')';
Select:
'SELECT' resultColumns+=ResultColumn (',' resultColumns+=ResultColumn)* 'FROM' source=TableSource;
TableSource:
table=[Table | ID] ('AS' alias=ID)?;
And now I am unsure how to implement "ResultColumn".
Quote:
ResultColumn:
tableSource=[TableSource|ID] '.' column=[ColumnDef|ID]
would work, with a ScopeProvider that assigns the TableSource elements with either the referenced table's name or the given alias. But it would break the code completion a bit, because I cannot put a combination like "tableName.columnName" into the scope. I guess I'd have to look into writing a custom ContentAssist then?
The alternative would be
Quote:
ResultColumn:
column=[Column | QualifiedName]
and then create Column-EObjects that have references to the referenced TableSource AND the referenced Column. But I don't really know how this would be done. I guess this problem arises in lots of situations, like referencing a member of a Java-like-instance where the actual Member-EObject would be defined within the class, not the instance. So I'm wondering how this is normally handled, haven't really understood that from reading the documentation so far.
Thanks in advance for any help!
Regards,
Tobias
|
|
|
Re: Crossreference to member of aliased container [message #757581 is a reply to message #757576] |
Sat, 19 November 2011 21:14 |
|
Hi,
i dont get your problem
you have 2 possibilities
(1) you do ResultColumn: tableSource=[TableSource|ID] '.' column=[ColumnDef|ID]
(2) ResultColumn: column=[ColumnDef|QualifiedName]
in (1) you have of course to write first the tablename, then the '.' and then the column name, but i do not see this as a "break of code completion"
in (2) have a look at
Model:
tables+=Table*
selects+=Select*;
Table:
{Table}'CREATE' 'TABLE' name=ID '(' columns+=ColumnDef (',' columns+=ColumnDef)* ')';
Select:
{Select}'SELECT' resultColumns+=ResultColumn (',' resultColumns+=ResultColumn)* 'FROM' source=TableSource;
ColumnDef:
name=ID "varchar32"
;
ResultColumn:
column=[ColumnDef | QualifiedName];
QualifiedName: ID "." ID;
TableSource:
table=[Table | ID] ('AS' alias=ID)?;
public class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
IScope scope_ResultColumn_column(Select select, EReference ref) {
if (select.getSource() != null && select.getSource().getTable() != null) {
List<IEObjectDescription> scope = new ArrayList<IEObjectDescription>();
Table table = select.getSource().getTable();
String alias = select.getSource().getAlias();
for (ColumnDef col : table.getColumns()) {
scope.add(EObjectDescription.create(QualifiedName.create(table.getName(), col.getName()), col));
if (alias != null) {
scope.add(EObjectDescription.create(QualifiedName.create(alias, col.getName()), col));
}
}
return new SimpleScope(scope);
} else {
return IScope.NULLSCOPE;
}
}
}
~Christian
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
[Updated on: Sat, 19 November 2011 21:18] Report message to a moderator
|
|
|
Re: Crossreference to member of aliased container [message #757584 is a reply to message #757581] |
Sat, 19 November 2011 21:32 |
|
Here the solution for the other way
Model:
tables+=Table*
selects+=Select*;
Table:
{Table}'CREATE' 'TABLE' name=ID '(' columns+=ColumnDef (',' columns+=ColumnDef)* ')';
Select:
{Select}'SELECT' resultColumns+=ResultColumn (',' resultColumns+=ResultColumn)* 'FROM' source=TableSource;
ColumnDef:
name=ID "varchar32"
;
ResultColumn:
table=[TableSource] "." column=[ColumnDef | ID];
TableSource:
table=[Table | ID] ('AS' alias=ID)?;
public class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
IScope scope_ResultColumn_column(ResultColumn rc, EReference ref) {
return Scopes.scopeFor(rc.getTable().getTable().getColumns());
}
IScope scope_ResultColumn_table(Select select, EReference ref) {
if (select.getSource() != null && select.getSource().getTable() != null) {
List<IEObjectDescription> scope = new ArrayList<IEObjectDescription>();
Table table = select.getSource().getTable();
String alias = select.getSource().getAlias();
scope.add(EObjectDescription.create(QualifiedName.create(table.getName()), select.getSource()));
if (alias != null) {
scope.add(EObjectDescription.create(QualifiedName.create(alias), select.getSource()));
}
return new SimpleScope(scope);
} else {
return IScope.NULLSCOPE;
}
}
}
ca is still a bit tricky with your grammar then
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
Powered by
FUDForum. Page generated in 0.03057 seconds