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

add type parameter constraints

This commit is contained in:
Kevin Glynn 2010-11-19 16:49:43 +01:00
parent 7f5b446e03
commit 3adfb22882
5 changed files with 95 additions and 78 deletions

View File

@ -640,8 +640,18 @@ attribute_argument_expression:
///////////////////////////////////////////////////////
class_declaration returns [string name]:
c='class' type_or_generic { $name = mkTypeName($type_or_generic.type, $type_or_generic.generic_arguments); } class_base? type_parameter_constraints_clauses? class_body ';'?
-> ^(CLASS[$c.Token] type_or_generic class_base? type_parameter_constraints_clauses? class_body );
c='class' identifier type_parameter_list? { $name = mkTypeName($identifier.text, $type_parameter_list.names); } class_base? type_parameter_constraints_clauses? class_body ';'?
-> ^(CLASS[$c.Token] identifier type_parameter_constraints_clauses? type_parameter_list? class_base? class_body );
type_parameter_list returns [List<string> names]
@init {
List<string> names = new List<string>();
}:
'<'! attributes? t1=type_parameter { names.Add($t1.name); } ( ','! attributes? tn=type_parameter { names.Add($tn.name); })* '>'! ;
type_parameter returns [string name]:
identifier { $name = $identifier.text; } ;
class_base:
// just put all types in a single list. In NetMaker we will extract the base class if necessary
':' interface_type_list -> ^(IMPLEMENTS interface_type_list);
@ -774,7 +784,9 @@ integral_type:
// B.2.12 Delegates
delegate_declaration returns [string name]:
'delegate' return_type identifier { $name = $identifier.text; } variant_generic_parameter_list?
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' ;
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' ->
'delegate' return_type identifier type_parameter_constraints_clauses? variant_generic_parameter_list?
'(' formal_parameter_list? ')' ';';
delegate_modifiers:
modifier+ ;
// 4.0
@ -782,33 +794,34 @@ variant_generic_parameter_list returns [List<string> tyargs]
@init {
$tyargs = new List<string>();
}:
'<' variant_type_parameters[$tyargs] '>' ;
'<'! variant_type_parameters[$tyargs] '>'! ;
variant_type_parameters [List<String> tyargs]:
v1=variant_type_variable_name { tyargs.Add($v1.text); } (',' vn=variant_type_variable_name { tyargs.Add($vn.text); })* ;
v1=variant_type_variable_name { tyargs.Add($v1.text); } (',' vn=variant_type_variable_name { tyargs.Add($vn.text); })* -> variant_type_variable_name+ ;
variant_type_variable_name:
attributes? variance_annotation? type_variable_name ;
variance_annotation:
'in' | 'out' ;
'in' -> IN | 'out' -> OUT;
type_parameter_constraints_clauses:
type_parameter_constraints_clause (',' type_parameter_constraints_clause)* ;
type_parameter_constraints_clause (',' type_parameter_constraints_clause)* -> type_parameter_constraints_clause+ ;
type_parameter_constraints_clause:
'where' type_variable_name ':' type_parameter_constraint_list ;
'where' type_variable_name ':' type_parameter_constraint_list -> ^(TYPE_PARAM_CONSTRAINT type_variable_name type_parameter_constraint_list?) ;
// class, Circle, new()
type_parameter_constraint_list:
('class' | 'struct') (',' secondary_constraint_list)? (',' constructor_constraint)?
| secondary_constraint_list (',' constructor_constraint)?
| constructor_constraint ;
('class' | 'struct') (',' secondary_constraint_list)? (',' constructor_constraint)? -> secondary_constraint_list?
| secondary_constraint_list (',' constructor_constraint)? -> secondary_constraint_list
| constructor_constraint -> ;
//primary_constraint:
// class_type
// | 'class'
// | 'struct' ;
secondary_constraint_list:
secondary_constraint (',' secondary_constraint)* ;
secondary_constraint (',' secondary_constraint)* -> secondary_constraint+ ;
secondary_constraint:
type_name ; // | type_variable_name) ;
type_variable_name:
identifier ;
// keving: TOTEST we drop new constraints, but what will happen in Java for this case?
constructor_constraint:
'new' '(' ')' ;
return_type:
@ -836,7 +849,7 @@ parameter_array:
interface_declaration returns [string name]:
c='interface' identifier { $name = $identifier.text; } variant_generic_parameter_list?
interface_base? type_parameter_constraints_clauses? interface_body ';'?
-> ^(INTERFACE[$c.Token] identifier variant_generic_parameter_list? interface_base? type_parameter_constraints_clauses? interface_body );
-> ^(INTERFACE[$c.Token] identifier type_parameter_constraints_clauses? variant_generic_parameter_list? interface_base? interface_body );
interface_base:
':' interface_type_list -> ^(EXTENDS interface_type_list);
@ -880,8 +893,8 @@ method_modifiers:
///////////////////////////////////////////////////////
struct_declaration returns [string name]:
c='struct' type_or_generic { $name = mkTypeName($type_or_generic.type, $type_or_generic.generic_arguments); } class_base? type_parameter_constraints_clauses? class_body ';'?
-> ^(CLASS[$c.Token] type_or_generic class_base? type_parameter_constraints_clauses? class_body );
c='struct' identifier type_parameter_list? { $name = mkTypeName($identifier.text, $type_parameter_list.names); } class_base? type_parameter_constraints_clauses? class_body ';'?
-> ^(CLASS[$c.Token] identifier type_parameter_constraints_clauses? type_parameter_list? class_base? class_body );
// UNUSED, HOPEFULLY
struct_modifiers:

View File

@ -318,9 +318,9 @@ qid_start:
qid_part:
access_identifier ;
generic_argument_list:
generic_argument_list:
'<' type_arguments '>' -> template(args={ $type_arguments.st }) "\<<args>\>";
type_arguments:
type_arguments:
ts+=type (',' ts+=type)* -> template(types = { $ts }) "<types; separator=\",\">";
type
@ -556,11 +556,21 @@ class_declaration[StringTemplate modifiersST]
@init {
List<string> preComments = null;
}:
^(c=CLASS { preComments = collectComments($c.TokenStartIndex); } type_or_generic
class_extends? class_implements? type_parameter_constraints_clauses? class_body )
-> class(modifiers = {modifiersST}, name={ $type_or_generic.st }, comments = { preComments },
^(c=CLASS { preComments = collectComments($c.TokenStartIndex); }
identifier type_parameter_constraints_clauses? type_parameter_list[$type_parameter_constraints_clauses.tpConstraints]?
class_extends? class_implements? class_body )
-> class(modifiers = {modifiersST}, name={ $identifier.st }, typeparams= {$type_parameter_list.st}, comments = { preComments },
extends = { $class_extends.st }, imps = { $class_implements.st }) ;
type_parameter_list [Dictionary<string,StringTemplate> tpConstraints]:
(attributes? t+=type_parameter[tpConstraints])+ -> template(params={ $t }) "\<<params; separator=\",\">\>";
type_parameter [Dictionary<string,StringTemplate> tpConstraints]
@init {
StringTemplate mySt = null;
}:
identifier {if (tpConstraints == null || !tpConstraints.TryGetValue($identifier.text, out mySt)) {mySt = $identifier.st;}; } -> { mySt } ;
class_extends:
^(EXTENDS ts+=type*) -> extends(types = { $ts }) ;
class_implements:
@ -658,39 +668,32 @@ integral_type:
// B.2.12 Delegates
delegate_declaration:
'delegate' return_type identifier variant_generic_parameter_list?
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' ;
'delegate' return_type identifier type_parameter_constraints_clauses? variant_generic_parameter_list[$type_parameter_constraints_clauses.tpConstraints]?
'(' formal_parameter_list? ')' ';' ;
delegate_modifiers:
modifier+ ;
// 4.0
variant_generic_parameter_list:
'<' variant_type_parameters '>' ;
variant_type_parameters:
variant_type_variable_name (',' variant_type_variable_name)* ;
variant_type_variable_name:
attributes? variance_annotation? type_variable_name ;
variant_generic_parameter_list [Dictionary<string,StringTemplate> tpConstraints]:
(ps+=variant_generic_parameter[$tpConstraints])+ -> template(params={$ps}) "<params; separator=\",\">";
variant_generic_parameter [Dictionary<string,StringTemplate> tpConstraints]:
attributes? variance_annotation? t=type_parameter[$tpConstraints] -> template(param={$t.st}, annotation={$variance_annotation.st}) "/* <annotation> */ <param>" ;
variance_annotation:
'in' | 'out' ;
IN -> template() "in" | OUT -> template() "out" ;
type_parameter_constraints_clauses:
type_parameter_constraints_clause (',' type_parameter_constraints_clause)* ;
type_parameter_constraints_clause:
'where' type_variable_name ':' type_parameter_constraint_list ;
// class, Circle, new()
type_parameter_constraint_list:
('class' | 'struct') (',' secondary_constraint_list)? (',' constructor_constraint)?
| secondary_constraint_list (',' constructor_constraint)?
| constructor_constraint ;
//primary_constraint:
// class_type
// | 'class'
// | 'struct' ;
secondary_constraint_list:
secondary_constraint (',' secondary_constraint)* ;
secondary_constraint:
type_name ; // | type_variable_name) ;
// tpConstraints is a map from type variable name to a string expressing the extends constraints
type_parameter_constraints_clauses returns [Dictionary<string,StringTemplate> tpConstraints]
@init {
$tpConstraints = new Dictionary<string,StringTemplate>();
}
:
ts+=type_parameter_constraints_clause[$tpConstraints]+ -> ;
type_parameter_constraints_clause [Dictionary<string,StringTemplate> tpConstraints]
@after{
tpConstraints[$t.text] = $type_parameter_constraints_clause.st;
}:
^(TYPE_PARAM_CONSTRAINT t=type_variable_name ts+=type_name+) -> type_param_constraint(param= { $type_variable_name.st }, constraints = { $ts }) ;
type_variable_name:
identifier ;
identifier -> { $identifier.st } ;
constructor_constraint:
'new' '(' ')' ;
return_type:
@ -719,9 +722,10 @@ interface_declaration[StringTemplate modifiersST]
@init {
List<string> preComments = null;
}:
^(c=INTERFACE { preComments = collectComments($c.TokenStartIndex); } identifier variant_generic_parameter_list?
class_extends? type_parameter_constraints_clauses? interface_body )
-> iface(modifiers = {modifiersST}, name={ $identifier.st }, comments = { preComments },
^(c=INTERFACE { preComments = collectComments($c.TokenStartIndex); }
identifier type_parameter_constraints_clauses? variant_generic_parameter_list[$type_parameter_constraints_clauses.tpConstraints]?
class_extends? interface_body )
-> iface(modifiers = {modifiersST}, name={ $identifier.st }, typeparams={$variant_generic_parameter_list.st} ,comments = { preComments },
imps = { $class_extends.st }) ;
interface_modifiers:
modifier+ ;

View File

@ -513,8 +513,15 @@ attribute_argument_expression:
///////////////////////////////////////////////////////
class_declaration:
^(CLASS type_or_generic
class_implements? type_parameter_constraints_clauses? class_body ) ;
^(CLASS identifier type_parameter_constraints_clauses? type_parameter_list?
class_implements? class_body ) ;
type_parameter_list:
(attributes? type_parameter)+ ;
type_parameter:
identifier ;
class_extends:
^(EXTENDS type*) ;
class_implements:
@ -610,37 +617,24 @@ integral_type:
// B.2.12 Delegates
delegate_declaration:
'delegate' return_type identifier variant_generic_parameter_list?
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' ;
'delegate' return_type identifier type_parameter_constraints_clauses? variant_generic_parameter_list?
'(' formal_parameter_list? ')' ';' ;
delegate_modifiers:
modifier+ ;
// 4.0
variant_generic_parameter_list:
'<' variant_type_parameters '>' ;
variant_type_parameters:
variant_type_variable_name (',' variant_type_variable_name)* ;
variant_type_variable_name+ ;
variant_type_variable_name:
attributes? variance_annotation? type_variable_name ;
variance_annotation:
'in' | 'out' ;
IN | OUT ;
type_parameter_constraints_clauses:
type_parameter_constraints_clause (',' type_parameter_constraints_clause)* ;
type_parameter_constraints_clause+ -> type_parameter_constraints_clause*;
type_parameter_constraints_clause:
'where' type_variable_name ':' type_parameter_constraint_list ;
// class, Circle, new()
type_parameter_constraint_list:
('class' | 'struct') (',' secondary_constraint_list)? (',' constructor_constraint)?
| secondary_constraint_list (',' constructor_constraint)?
| constructor_constraint ;
//primary_constraint:
// class_type
// | 'class'
// | 'struct' ;
secondary_constraint_list:
secondary_constraint (',' secondary_constraint)* ;
secondary_constraint:
type_name ; // | type_variable_name) ;
// If there are no type constraints on this variable then drop this constraint
^(TYPE_PARAM_CONSTRAINT type_variable_name) ->
| ^(TYPE_PARAM_CONSTRAINT type_variable_name type_name+) ;
type_variable_name:
identifier ;
constructor_constraint:
@ -668,8 +662,8 @@ parameter_array:
///////////////////////////////////////////////////////
interface_declaration:
^(INTERFACE identifier variant_generic_parameter_list?
class_extends? type_parameter_constraints_clauses? interface_body ) ;
^(INTERFACE identifier type_parameter_constraints_clauses? variant_generic_parameter_list?
class_extends? interface_body ) ;
interface_modifiers:
modifier+ ;
interface_base:

View File

@ -8,13 +8,17 @@ options {
tokens {
PACKAGE;
ENUM_BODY;
CLASS;
EXTENDS;
IMPLEMENTS;
INTERFACE;
FINAL; /* final modifier */
IN;
OUT;
ENUM_BODY;
TYPE_PARAM_CONSTRAINT;
PAYLOAD; // carries arbitrary text for the output file
PAYLOAD_LIST;
}

View File

@ -28,9 +28,9 @@ package <packageName>;
// ******* CLASSES ***********
class(modifiers, comments, attributes, name, inherits, body) ::= <<
class(modifiers, comments, attributes, name, typeparams, inherits, body) ::= <<
<comments; separator="\n">
<modifiers(modifiers)>class <name> <inherits>
<modifiers(modifiers)>class <name> <typeparams> <inherits>
{
<body>
}
@ -44,6 +44,8 @@ iface(modifiers, comments, attributes, name, imps, body) ::= <<
}
>>
type_param_constraint(param, constraints) ::= "<param> extends <constraints; separator=\" & \">"
// ******* ENUMS ***********
enum(modifiers,comments, attributes, name, body) ::= <<