1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00

resolve simple property reads

This commit is contained in:
Kevin Glynn 2011-01-13 10:38:33 +01:00
parent 4c9cc2dd4a
commit d4d24341ac
6 changed files with 128 additions and 5 deletions

View File

@ -1334,6 +1334,30 @@ namespace RusticiSoftware.Translator.CLR
return new InterfaceRep ();
}
public virtual TranslationBase Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv)
{
if (Properties != null)
{
foreach (PropRepTemplate p in Properties)
{
if (p.Name == name)
return p;
}
}
if (Inherits != null)
{
foreach (String b in Inherits)
{
TranslationBase ret = ((InterfaceRepTemplate)AppEnv.Search(Uses, b)).Resolve(name,AppEnv);
if (ret != null)
return ret;
}
}
return null;
}
#region Equality
public bool Equals (InterfaceRepTemplate other)
{
@ -1526,6 +1550,21 @@ namespace RusticiSoftware.Translator.CLR
return new ClassRep ();
}
public override TranslationBase Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv)
{
if (Fields != null)
{
foreach (FieldRepTemplate f in Fields)
{
if (f.Name == name)
return f;
}
}
return base.Resolve(name, AppEnv);
}
#region Equality
public bool Equals (ClassRepTemplate other)
{
@ -1658,6 +1697,11 @@ namespace RusticiSoftware.Translator.CLR
return new StructRep ();
}
public override TranslationBase Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv)
{
return base.Resolve(name, AppEnv);
}
#region Equality
public bool Equals (StructRepTemplate other)
{
@ -1748,4 +1792,9 @@ namespace RusticiSoftware.Translator.CLR
}
}

View File

@ -95,6 +95,7 @@ namespace RusticiSoftware.Translator.CSharp
buf.Append(">");
return buf.ToString();
}
}
// Wraps a compilation unit with its imports search path

View File

@ -239,6 +239,7 @@ scope TypeContext {
protected CommonTree dupTree(CommonTree t) {
return (CommonTree)adaptor.DupTree(t);
}
}
/********************************************************************************************

View File

@ -214,6 +214,30 @@ options {
public int comparePrecedence(int parentPrec, int childPrec) {
return Math.Sign(childPrec-parentPrec);
}
// cleverly remove any remaining ${..} tokens
public string cleanTemplate(string template) {
// Are there any markers in the template? Mostly, the answer will be no and we can return tout-de-suite
String ret = template;
if (Regex.IsMatch(ret, "\\$\\{.*\\}")) {
// ${this}.fred -> fred
ret = Regex.Replace(ret, "\\$\\{.*\\}\\.", String.Empty);
// (a,${var},b) -> (a,b)
ret = Regex.Replace(ret, "\\$\\{.*\\},", String.Empty);
// (a,${var}) -> (a)
ret = Regex.Replace(ret, ",\\$\\{.*\\}", String.Empty);
// (${var}) -> ()
ret = Regex.Replace(ret, "\\$\\{.*\\}", String.Empty);
}
return ret;
}
public string fillTemplate(string template, Dictionary<string,string> templateMap) {
String ret = template;
foreach (string v in templateMap.Keys) {
ret = ret.Replace("${" + v + "}", templateMap[v]);
}
ret = cleanTemplate(ret);
return ret;
}
}
compilation_unit
@ -280,8 +304,10 @@ exception:
primary_expression returns [int precedence]
@init {
$precedence = int.MaxValue;
Dictionary<string,string> templateMap = new Dictionary<string,string>();
}:
^(INDEX expression expression_list?) { $precedence = precedence[INDEX]; } -> index(func= { $expression.st }, funcparens = { comparePrecedence(precedence[INDEX], $expression.precedence) < 0 }, args = { $expression_list.st } )
^(JAVAWRAPPER t=identifier (k=identifier v=expression { templateMap[$k.st.ToString()] = $v.st.ToString(); })*) -> string(payload = { fillTemplate($t.st.ToString(), templateMap) })
| ^(INDEX expression expression_list?) { $precedence = precedence[INDEX]; } -> index(func= { $expression.st }, funcparens = { comparePrecedence(precedence[INDEX], $expression.precedence) < 0 }, args = { $expression_list.st } )
| ^(APPLY expression argument_list?) { $precedence = precedence[APPLY]; } -> application(func= { $expression.st }, funcparens = { comparePrecedence(precedence[APPLY], $expression.precedence) < 0 }, args = { $argument_list.st } )
| ^((op=POSTINC|op=POSTDEC) expression) { $precedence = precedence[$op.token.Type]; }
-> op(pre={$expression.st}, op={ $op.token.Text }, preparens= { comparePrecedence($op.token, $expression.precedence) <= 0 })

View File

@ -113,6 +113,38 @@ scope SymTab {
}
return def;
}
protected CommonTree mkJavaWrapper(string template, Dictionary<string,CommonTree> varMap, IToken tok) {
CommonTree root = (CommonTree)adaptor.Nil;
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(JAVAWRAPPER, tok, "JAVAWRAPPER"), root);
adaptor.AddChild(root, (CommonTree)adaptor.Create(IDENTIFIER, tok, template));
if (varMap != null) {
foreach (String var in varMap.Keys) {
if (varMap[var] != null) {
adaptor.AddChild(root, (CommonTree)adaptor.Create(IDENTIFIER, tok, var));
adaptor.AddChild(root, dupTree(varMap[var]));
}
}
}
return (CommonTree)adaptor.RulePostProcessing(root);
}
// Resolve Routines
protected String ResolveGetter(InterfaceRepTemplate thisType, CommonTree thisExp, String name) {
String ret = null;
PropRepTemplate entity = thisType.Resolve(name, AppEnv) as PropRepTemplate;
if (entity != null) {
ret = entity.JavaGet;
}
return ret;
}
protected CommonTree dupTree(CommonTree t) {
return (CommonTree)adaptor.DupTree(t);
}
}
compilation_unit
@ -170,6 +202,11 @@ scope {
}
@init {
$primary_expression::parentIsApply = false;
CommonTree ret = null;
}
@after {
if (ret != null)
$primary_expression.tree = ret;
}:
^(INDEX expression expression_list?)
// | ^(APPLY identifier argument_list?)
@ -181,18 +218,26 @@ scope {
| predefined_type { $dotNetType = $predefined_type.dotNetType; }
| 'this' { $dotNetType = SymTabLookup("this"); }
| SUPER { $dotNetType = SymTabLookup("super"); }
| identifier
| i=identifier
{
TypeRepTemplate idType = SymTabLookup($identifier.thetext);
if (idType == null) {
// Not a variable
// Is it a property? Enusre we are not being applied to arguments or about to be assigned
if (($primary_expression.Count == 1 || !((primary_expression_scope)($primary_expression.ToArray()[1])).parentIsApply) &&
// Is it a property? Ensure we are not being applied to arguments or about to be assigned
InterfaceRepTemplate thisType = SymTabLookup("this") as InterfaceRepTemplate;
if (thisType != null &&
($primary_expression.Count == 1 || !((primary_expression_scope)($primary_expression.ToArray()[1])).parentIsApply) &&
($assignment.Count == 0 || !$assignment::parentIsSetter)) {
Debug($identifier.tree.Token.Line + ": '" + $identifier.thetext + "' might be a property");
String template = ResolveGetter(thisType, null, $identifier.thetext);
if (template != null) {
Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'");
// Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
// myMap["this"] = null;
ret = mkJavaWrapper(template, null, $i.tree.Token);
}
}
}
$dotNetType = idType;
}

View File

@ -126,6 +126,7 @@ tokens {
PAYLOAD; // carries arbitrary text for the output file
PAYLOAD_LIST;
JAVAWRAPPER;
SEP;
KGHOLE;
}