mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
- ForceUnsharedType::share allows to force a copy of the type in case we want to update it latter (e.g. IsWrapped)
- use rewriteXXXX methods from base
This commit is contained in:
parent
b5f2f3126b
commit
37b80a1fbd
@ -47,6 +47,11 @@ scope PrimitiveRep {
|
|||||||
bool primitiveTypeAsObject;
|
bool primitiveTypeAsObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When this scope is true, then type should generate a fresh dotNetType so that we can update it without affecting all other types
|
||||||
|
scope ForceUnsharedType {
|
||||||
|
bool fresh;
|
||||||
|
}
|
||||||
|
|
||||||
// When this scope is true, then strip generic arguments from types
|
// When this scope is true, then strip generic arguments from types
|
||||||
// (In Java the runtime doesn't know the generic types so e.g. instanceof Set<T>
|
// (In Java the runtime doesn't know the generic types so e.g. instanceof Set<T>
|
||||||
// must be just instanceof Set).
|
// must be just instanceof Set).
|
||||||
@ -114,11 +119,41 @@ scope MkNonGeneric {
|
|||||||
return findType(name.Type);
|
return findType(name.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<string,string> builtinTypeMap = null;
|
||||||
|
private Dictionary<string,string> BuiltinTypeMap {
|
||||||
|
get {
|
||||||
|
if (builtinTypeMap == null) {
|
||||||
|
builtinTypeMap = new Dictionary<string,string>();
|
||||||
|
builtinTypeMap["bool"] = "System.Boolean";
|
||||||
|
builtinTypeMap["byte"] = Cfg.UnsignedNumbersToSigned ? "System.SByte" : "System.Byte";
|
||||||
|
builtinTypeMap["char"] = "System.Char";
|
||||||
|
builtinTypeMap["decimal"] = "System.Decimal";
|
||||||
|
builtinTypeMap["double"] = "System.Double";
|
||||||
|
builtinTypeMap["float"] = "System.Single";
|
||||||
|
builtinTypeMap["int"] = "System.Int32";
|
||||||
|
builtinTypeMap["long"] = "System.Int64";
|
||||||
|
builtinTypeMap["object"] = "System.Object";
|
||||||
|
builtinTypeMap["sbyte"] = "System.Byte";
|
||||||
|
builtinTypeMap["short"] = "System.Int16";
|
||||||
|
builtinTypeMap["string"] = "system.String";
|
||||||
|
builtinTypeMap["uint"] = Cfg.UnsignedNumbersToSigned ? "System.Int32" : "System.UInt32";
|
||||||
|
builtinTypeMap["ulong"] = Cfg.UnsignedNumbersToSigned ? "System.Int64" : "System.UInt64";
|
||||||
|
builtinTypeMap["ushort"] = Cfg.UnsignedNumbersToSigned ? "System.Int16" : "System.UInt16";
|
||||||
|
builtinTypeMap["void"] = "System.Void";
|
||||||
|
}
|
||||||
|
return builtinTypeMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected TypeRepTemplate findType(string name) {
|
protected TypeRepTemplate findType(string name) {
|
||||||
if ($NSContext.Count > 0 && $NSContext::globalTypeVariables != null && $NSContext::globalTypeVariables.Contains(name)) {
|
if ($NSContext.Count > 0 && $NSContext::globalTypeVariables != null && $NSContext::globalTypeVariables.Contains(name)) {
|
||||||
return new TypeVarRepTemplate(name);
|
return new TypeVarRepTemplate(name);
|
||||||
}
|
}
|
||||||
return AppEnv.Search($NSContext.Count > 0 ? $NSContext::globalNamespaces : null, name, new UnknownRepTemplate(name));
|
string fullName = name;
|
||||||
|
if (BuiltinTypeMap.ContainsKey(name)) {
|
||||||
|
fullName = BuiltinTypeMap[name];
|
||||||
|
}
|
||||||
|
return AppEnv.Search($NSContext.Count > 0 ? $NSContext::globalNamespaces : null, fullName, new UnknownRepTemplate(fullName));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TypeRepTemplate findType(string name, ICollection<TypeRepTemplate> args) {
|
protected TypeRepTemplate findType(string name, ICollection<TypeRepTemplate> args) {
|
||||||
@ -826,7 +861,7 @@ scope MkNonGeneric {
|
|||||||
|
|
||||||
adaptor.AddChild(method, retTypeRoot);
|
adaptor.AddChild(method, retTypeRoot);
|
||||||
|
|
||||||
adaptor.AddChild(method, (CommonTree)adaptor.Create(IDENTIFIER, tok, "GetInvocationList"));
|
adaptor.AddChild(method, (CommonTree)adaptor.Create(IDENTIFIER, tok, rewriteMethodName("GetInvocationList")));
|
||||||
|
|
||||||
adaptor.AddChild(method, (CommonTree)adaptor.Create(OPEN_BRACE, tok, "{"));
|
adaptor.AddChild(method, (CommonTree)adaptor.Create(OPEN_BRACE, tok, "{"));
|
||||||
|
|
||||||
@ -922,7 +957,7 @@ scope MkNonGeneric {
|
|||||||
adaptor.AddChild(retTypeRoot, (CommonTree)adaptor.Create(IDENTIFIER, tok, returnType.Java));
|
adaptor.AddChild(retTypeRoot, (CommonTree)adaptor.Create(IDENTIFIER, tok, returnType.Java));
|
||||||
adaptor.AddChild(method, retTypeRoot);
|
adaptor.AddChild(method, retTypeRoot);
|
||||||
|
|
||||||
adaptor.AddChild(method, (CommonTree)adaptor.Create(IDENTIFIER, tok, "Invoke"));
|
adaptor.AddChild(method, (CommonTree)adaptor.Create(IDENTIFIER, tok, rewriteMethodName("Invoke")));
|
||||||
if (delg.Invoke.Params.Count > 0) {
|
if (delg.Invoke.Params.Count > 0) {
|
||||||
adaptor.AddChild(method, mkParams(delg, delg.Invoke.Params, true, tok));
|
adaptor.AddChild(method, mkParams(delg, delg.Invoke.Params, true, tok));
|
||||||
}
|
}
|
||||||
@ -986,7 +1021,7 @@ scope MkNonGeneric {
|
|||||||
adaptor.AddChild(retTypeRoot, (CommonTree)adaptor.Create(IDENTIFIER, tok, returnType.Java));
|
adaptor.AddChild(retTypeRoot, (CommonTree)adaptor.Create(IDENTIFIER, tok, returnType.Java));
|
||||||
adaptor.AddChild(method, retTypeRoot);
|
adaptor.AddChild(method, retTypeRoot);
|
||||||
|
|
||||||
adaptor.AddChild(method, (CommonTree)adaptor.Create(IDENTIFIER, tok, "Invoke"));
|
adaptor.AddChild(method, (CommonTree)adaptor.Create(IDENTIFIER, tok, rewriteMethodName("Invoke")));
|
||||||
adaptor.AddChild(method, dupTree(argsTree));
|
adaptor.AddChild(method, dupTree(argsTree));
|
||||||
adaptor.AddChild(method, dupTree(bodyTree));
|
adaptor.AddChild(method, dupTree(bodyTree));
|
||||||
adaptor.AddChild(method, (CommonTree)adaptor.Create(EXCEPTION, tok, "Exception"));
|
adaptor.AddChild(method, (CommonTree)adaptor.Create(EXCEPTION, tok, "Exception"));
|
||||||
@ -998,6 +1033,19 @@ scope MkNonGeneric {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new <delegate_type>() { public void Invoke(<formal args>) throw exception <body> }
|
||||||
|
protected CommonTree rewriteMethodGroupName(CommonTree methodGroupNameId) {
|
||||||
|
CommonTree ret = null;
|
||||||
|
if (adaptor.GetType(methodGroupNameId) == IDENTIFIER) {
|
||||||
|
ret = (CommonTree)adaptor.Nil;
|
||||||
|
ret = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(IDENTIFIER, adaptor.GetToken(methodGroupNameId), rewriteMethodName(adaptor.GetToken(methodGroupNameId).Text)), ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = dupTree(methodGroupNameId);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Used from parseString() to set up dynamic scopes
|
// Used from parseString() to set up dynamic scopes
|
||||||
public override void InitParser()
|
public override void InitParser()
|
||||||
{
|
{
|
||||||
@ -1006,6 +1054,7 @@ scope MkNonGeneric {
|
|||||||
PrimitiveRep_stack.Push(new PrimitiveRep_scope());
|
PrimitiveRep_stack.Push(new PrimitiveRep_scope());
|
||||||
MkNonGeneric_stack.Push(new MkNonGeneric_scope());
|
MkNonGeneric_stack.Push(new MkNonGeneric_scope());
|
||||||
SymTab_stack.Push(new SymTab_scope());
|
SymTab_stack.Push(new SymTab_scope());
|
||||||
|
ForceUnsharedType_stack.Push(new ForceUnsharedType_scope());
|
||||||
// Set up dynamic scopes
|
// Set up dynamic scopes
|
||||||
|
|
||||||
$PrimitiveRep::primitiveTypeAsObject = false;
|
$PrimitiveRep::primitiveTypeAsObject = false;
|
||||||
@ -1023,11 +1072,12 @@ scope MkNonGeneric {
|
|||||||
|
|
||||||
$SymTab::symtab = new Dictionary<string,TypeRepTemplate>();
|
$SymTab::symtab = new Dictionary<string,TypeRepTemplate>();
|
||||||
|
|
||||||
|
$ForceUnsharedType::fresh = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public compilation_unit
|
public compilation_unit
|
||||||
scope NSContext, PrimitiveRep, MkNonGeneric;
|
scope NSContext, PrimitiveRep, MkNonGeneric, ForceUnsharedType;
|
||||||
@init {
|
@init {
|
||||||
|
|
||||||
$PrimitiveRep::primitiveTypeAsObject = false;
|
$PrimitiveRep::primitiveTypeAsObject = false;
|
||||||
@ -1044,6 +1094,8 @@ scope NSContext, PrimitiveRep, MkNonGeneric;
|
|||||||
$NSContext::interfaceList = new List<InterfaceRepTemplate>();
|
$NSContext::interfaceList = new List<InterfaceRepTemplate>();
|
||||||
$NSContext::blackListedMethods = new List<string>();
|
$NSContext::blackListedMethods = new List<string>();
|
||||||
|
|
||||||
|
$ForceUnsharedType::fresh = false;
|
||||||
|
|
||||||
}:
|
}:
|
||||||
^(pkg=PACKAGE ns=PAYLOAD { $NSContext::currentNS = $ns.text; } dec=type_declaration )
|
^(pkg=PACKAGE ns=PAYLOAD { $NSContext::currentNS = $ns.text; } dec=type_declaration )
|
||||||
-> ^($pkg $ns { mkImports() } $dec);
|
-> ^($pkg $ns { mkImports() } $dec);
|
||||||
@ -1138,13 +1190,8 @@ scope SymTab;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (Optionally) rewrite the method name
|
// (Optionally) rewrite the method name
|
||||||
if ($identifier.thetext != "Main") {
|
if (!$NSContext::blackListedMethods.Contains($identifier.thetext)) {
|
||||||
if (!$NSContext::blackListedMethods.Contains($identifier.thetext)) {
|
$identifier.tree.Token.Text = rewriteMethodName($identifier.thetext);
|
||||||
if (Cfg.TranslatorMakeJavaNamingConventions) {
|
|
||||||
// Leave Main() as it is because we wrap it with a special main method
|
|
||||||
$identifier.tree.Token.Text = toJavaConvention(CSharpEntity.METHOD, $identifier.thetext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
-> ^(METHOD attributes? modifiers? { dupTree(methodTemplate != null && methodTemplate.Return.ForceBoxed && $type.boxedTree != null ? $type.boxedTree : $type.tree) }
|
-> ^(METHOD attributes? modifiers? { dupTree(methodTemplate != null && methodTemplate.Return.ForceBoxed && $type.boxedTree != null ? $type.boxedTree : $type.tree) }
|
||||||
@ -1355,7 +1402,10 @@ scope {
|
|||||||
| 'this' { $dotNetType = SymTabLookup("this"); }
|
| 'this' { $dotNetType = SymTabLookup("this"); }
|
||||||
| SUPER { $dotNetType = SymTabLookup("super"); }
|
| SUPER { $dotNetType = SymTabLookup("super"); }
|
||||||
| (^(d1='.' e1=expression[ObjectType] {expType = $e1.dotNetType; implicitThis = false; e1Tree = dupTree($e1.tree); /* keving: yuk, shouldn't be necessary but $e1.tree was also capturing i=identifier */} i=identifier dgal=generic_argument_list?)
|
| (^(d1='.' e1=expression[ObjectType] {expType = $e1.dotNetType; implicitThis = false; e1Tree = dupTree($e1.tree); /* keving: yuk, shouldn't be necessary but $e1.tree was also capturing i=identifier */} i=identifier dgal=generic_argument_list?)
|
||||||
|(i=identifier dgal=generic_argument_list?)) magicInputPeId[$d1.tree,$i.tree,$dgal.tree]
|
|(i=identifier dgal=generic_argument_list?))
|
||||||
|
magicIdentifier[true, rewriteMethodName($i.thetext), $i.tree != null ? $i.tree.Token : null]
|
||||||
|
magicInputPeId[$d1.tree,$i.tree,$dgal.tree]
|
||||||
|
magicMethodGroup[$d1.tree, $e1.tree, $magicIdentifier.tree, $dgal.tree, $i.tree != null ? $i.tree.Token : null]
|
||||||
{
|
{
|
||||||
// TODO: generic_argument_list is ignored ....
|
// TODO: generic_argument_list is ignored ....
|
||||||
|
|
||||||
@ -1426,7 +1476,7 @@ scope {
|
|||||||
// use an anonymous inner class to generate a delegate object (object wih an Invoke with appropriate arguments)
|
// use an anonymous inner class to generate a delegate object (object wih an Invoke with appropriate arguments)
|
||||||
// new <delegate_name>() { public void Invoke(<formal args>) throw exception { [return] arg[0](<args>); } }
|
// new <delegate_name>() { public void Invoke(<formal args>) throw exception { [return] arg[0](<args>); } }
|
||||||
DelegateRepTemplate delType = $typeCtxt as DelegateRepTemplate;
|
DelegateRepTemplate delType = $typeCtxt as DelegateRepTemplate;
|
||||||
ret = mkDelegateObject((CommonTree)$typeCtxt.Tree, $magicInputPeId.tree, delType, $i.tree.Token);
|
ret = mkDelegateObject((CommonTree)$typeCtxt.Tree, $magicMethodGroup.tree, delType, $i.tree.Token);
|
||||||
$dotNetType = $typeCtxt;
|
$dotNetType = $typeCtxt;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
@ -1461,7 +1511,7 @@ scope {
|
|||||||
// use an anonymous inner class to generate a delegate object (object wih an Invoke with appropriate arguments)
|
// use an anonymous inner class to generate a delegate object (object wih an Invoke with appropriate arguments)
|
||||||
// new <delegate_name>() { public void Invoke(<formal args>) throw exception { [return] arg[0](<args>); } }
|
// new <delegate_name>() { public void Invoke(<formal args>) throw exception { [return] arg[0](<args>); } }
|
||||||
DelegateRepTemplate delType = $type.dotNetType as DelegateRepTemplate;
|
DelegateRepTemplate delType = $type.dotNetType as DelegateRepTemplate;
|
||||||
ret = mkDelegateObject($type.tree, (CommonTree)adaptor.GetChild($argument_list.tree, 0), delType, $n.token);
|
ret = mkDelegateObject($type.tree, rewriteMethodGroupName((CommonTree)adaptor.GetChild($argument_list.tree, 0)), delType, $n.token);
|
||||||
$dotNetType = $type.dotNetType;
|
$dotNetType = $type.dotNetType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1836,12 +1886,16 @@ type returns [TypeRepTemplate dotNetType, List<CommonTree> argTrees, CommonTree
|
|||||||
CommonTree pTree = null;
|
CommonTree pTree = null;
|
||||||
}
|
}
|
||||||
@after {
|
@after {
|
||||||
if ($dotNetType.Tree == null) {
|
|
||||||
$dotNetType.Tree = $type.tree;
|
|
||||||
}
|
|
||||||
if ($boxedTree == null) {
|
if ($boxedTree == null) {
|
||||||
$boxedTree = $type.tree;
|
$boxedTree = $type.tree;
|
||||||
}
|
}
|
||||||
|
if ($ForceUnsharedType::fresh) {
|
||||||
|
$dotNetType = $dotNetType.Instantiate(null);
|
||||||
|
}
|
||||||
|
if ($dotNetType.Tree == null) {
|
||||||
|
$dotNetType.Tree = $type.tree;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
^(t=TYPE (p=predefined_type { isPredefined = true; $dotNetType = $predefined_type.dotNetType; pTree = $p.tree; }
|
^(t=TYPE (p=predefined_type { isPredefined = true; $dotNetType = $predefined_type.dotNetType; pTree = $p.tree; }
|
||||||
@ -2816,9 +2870,11 @@ formal_parameter[ParamRepTemplate pInfo, ParamArrayRepTemplate paInfo] returns [
|
|||||||
|
|
||||||
fixed_parameter[ParamRepTemplate pInfo] returns [TypeRepTemplate paramType, CommonTree boxedTypeTree]
|
fixed_parameter[ParamRepTemplate pInfo] returns [TypeRepTemplate paramType, CommonTree boxedTypeTree]
|
||||||
scope PrimitiveRep;
|
scope PrimitiveRep;
|
||||||
|
scope ForceUnsharedType;
|
||||||
@init {
|
@init {
|
||||||
$PrimitiveRep::primitiveTypeAsObject = $pInfo != null ? $pInfo.Type.ForceBoxed : false;
|
$PrimitiveRep::primitiveTypeAsObject = $pInfo != null ? $pInfo.Type.ForceBoxed : false;
|
||||||
bool isRefOut = false;
|
bool isRefOut = false;
|
||||||
|
bool oldFresh = false;
|
||||||
}:
|
}:
|
||||||
(parameter_modifier
|
(parameter_modifier
|
||||||
{ isRefOut = $parameter_modifier.isRefOut;
|
{ isRefOut = $parameter_modifier.isRefOut;
|
||||||
@ -2827,7 +2883,10 @@ scope PrimitiveRep;
|
|||||||
AddToImports("CS2JNet.JavaSupport.language.RefSupport");
|
AddToImports("CS2JNet.JavaSupport.language.RefSupport");
|
||||||
}
|
}
|
||||||
})?
|
})?
|
||||||
|
// make a copy of the type parameter so that we can set iswrapped below
|
||||||
|
{ oldFresh = $ForceUnsharedType::fresh; $ForceUnsharedType::fresh = isRefOut;}
|
||||||
type { $boxedTypeTree = $type.boxedTree; }
|
type { $boxedTypeTree = $type.boxedTree; }
|
||||||
|
{ $ForceUnsharedType::fresh = oldFresh; }
|
||||||
identifier { $paramType = $type.dotNetType; $type.dotNetType.IsWrapped = isRefOut; $SymTab::symtab[$identifier.thetext] = $type.dotNetType; }
|
identifier { $paramType = $type.dotNetType; $type.dotNetType.IsWrapped = isRefOut; $SymTab::symtab[$identifier.thetext] = $type.dotNetType; }
|
||||||
default_argument?
|
default_argument?
|
||||||
magicRef[isRefOut, $type.tree != null ? $type.tree.Token : null, $type.tree]
|
magicRef[isRefOut, $type.tree != null ? $type.tree.Token : null, $type.tree]
|
||||||
@ -2872,11 +2931,8 @@ scope SymTab;
|
|||||||
-> ^(METHOD[$e.token, "METHOD"] attributes? modifiers? magicEventCollectionType identifier EXCEPTION[$i.tree.Token, "Exception"])
|
-> ^(METHOD[$e.token, "METHOD"] attributes? modifiers? magicEventCollectionType identifier EXCEPTION[$i.tree.Token, "Exception"])
|
||||||
| ^(METHOD attributes? modifiers? type identifier type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list[null,null]? exception*)
|
| ^(METHOD attributes? modifiers? type identifier type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list[null,null]? exception*)
|
||||||
{
|
{
|
||||||
if ($identifier.thetext != "Main" && Cfg.TranslatorMakeJavaNamingConventions) {
|
$identifier.tree.Token.Text = rewriteMethodName($identifier.thetext);
|
||||||
// Leave Main() as it is because we are going to wrap it with a special main method
|
}
|
||||||
$identifier.tree.Token.Text = toJavaConvention(CSharpEntity.METHOD, $identifier.thetext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
@ -3325,28 +3381,27 @@ yield_statement:
|
|||||||
|
|
||||||
predefined_type returns [TypeRepTemplate dotNetType]
|
predefined_type returns [TypeRepTemplate dotNetType]
|
||||||
@init {
|
@init {
|
||||||
string ns = "";
|
bool unBoxed = true;
|
||||||
}
|
}
|
||||||
@after {
|
@after {
|
||||||
$dotNetType = new ClassRepTemplate((ClassRepTemplate)AppEnv.Search(ns, new UnknownRepTemplate(ns)));
|
$dotNetType = findType($predefined_type.text);
|
||||||
$dotNetType.IsUnboxedType = true;
|
$dotNetType.IsUnboxedType = unBoxed;
|
||||||
string newText = null;
|
|
||||||
}:
|
}:
|
||||||
'bool' { ns = "System.Boolean"; }
|
'bool'
|
||||||
| 'byte' { ns = Cfg.UnsignedNumbersToSigned ? "System.SByte" : "System.Byte"; }
|
| 'byte'
|
||||||
| 'char' { ns = "System.Char"; }
|
| 'char'
|
||||||
| 'decimal' { ns = "System.Decimal"; }
|
| 'decimal'
|
||||||
| 'double' { ns = "System.Double"; }
|
| 'double'
|
||||||
| 'float' { ns = "System.Single"; }
|
| 'float'
|
||||||
| 'int' { ns = "System.Int32"; }
|
| 'int'
|
||||||
| 'long' { ns = "System.Int64"; }
|
| 'long'
|
||||||
| 'object' { ns = "System.Object"; }
|
| 'object'
|
||||||
| 'sbyte' { ns = "System.Byte"; }
|
| 'sbyte'
|
||||||
| 'short' { ns = "System.Int16"; }
|
| 'short'
|
||||||
| 'string' { ns = "System.String"; }
|
| 'string' { unBoxed = false; }
|
||||||
| 'uint' { ns = Cfg.UnsignedNumbersToSigned ? "System.Int32" : "System.UInt32"; }
|
| 'uint'
|
||||||
| 'ulong' { ns = Cfg.UnsignedNumbersToSigned ? "System.Int64" : "System.UInt64"; }
|
| 'ulong'
|
||||||
| 'ushort' { ns = Cfg.UnsignedNumbersToSigned ? "System.Int16" : "System.UInt16"; }
|
| 'ushort'
|
||||||
;
|
;
|
||||||
|
|
||||||
// Don't trust identifier.text in tree grammars: Doesn't work for our magic additions because the text function goes back to the
|
// Don't trust identifier.text in tree grammars: Doesn't work for our magic additions because the text function goes back to the
|
||||||
@ -3692,3 +3747,13 @@ magicExtends[bool isOn, IToken tok, CommonTree type]:
|
|||||||
-> { $isOn }? ^(EXTENDS[tok, "extends"] { dupTree($type) })
|
-> { $isOn }? ^(EXTENDS[tok, "extends"] { dupTree($type) })
|
||||||
->
|
->
|
||||||
;
|
;
|
||||||
|
|
||||||
|
magicIdentifier[bool isOn, string text, IToken tok]:
|
||||||
|
-> { $isOn }? ^(IDENTIFIER[tok, text])
|
||||||
|
->
|
||||||
|
;
|
||||||
|
|
||||||
|
magicMethodGroup[CommonTree d1Tree, CommonTree e1Tree, CommonTree idTree, CommonTree galTree, IToken tok]:
|
||||||
|
-> { $d1Tree == null }? {dupTree(idTree)} {dupTree(galTree)}
|
||||||
|
-> ^(DOT[tok, "."] {dupTree(e1Tree)} {dupTree(idTree)} {dupTree(galTree)})
|
||||||
|
;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user