%%%
 %% Section 4.3: Reference Types and Values
 %%
 %% @author Martin Bravenboer <martin@cs.uu.nl>
 %%%
module languages/java-15/types/ReferenceTypes
imports
  languages/java-15/lexical/Identifiers
  languages/java-15/names/Main
  languages/java-15/types/Main  
  languages/java-15/types/ParameterizedTypes
  languages/java-15/types/TypeVariables


exports
  sorts
    RefType
    ClassOrInterfaceType
    ClassType
    InterfaceType
    TypeDecSpec
    ArrayType
    TypeVar

  context-free syntax
    ClassOrInterfaceType -> RefType
    ArrayType            -> RefType
    
    %% This production rule is highly ambiguous, since every
    %% TypeVar can be a ClassOrInterfaceType. A later disambiguation
    %% phase has to find out if a ClassOrInterfaceType is in fact
    %% a TypeVar.
    
    %% TypeVar -> RefType {avoid}

  context-free syntax
  
    %% ClassType and InterfaceType are ambiguous. We modify the
    %% production of ClassOrInterfaceType to make this ambiguity explicit.
    
    TypeDecSpec TypeArgs? -> ClassOrInterfaceType {cons("ClassOrInterfaceType")}
    TypeDecSpec TypeArgs? -> ClassType {cons("ClassType")}
    TypeDecSpec TypeArgs? -> InterfaceType {cons("InterfaceType")}

    %% The two production rules for TypeDecSpec are ambiguous,
    %% since any TypeDecSpec can be represented by the second
    %% production rule. To workaround this, we prefer the simple
    %% TypeName. A later disambiguation phase has to find out if 
    %% this TypeName is in fact a Member.
    
    TypeName                    -> TypeDecSpec {prefer}
    ClassOrInterfaceType "." Id -> TypeDecSpec {cons("Member")}
    
  context-free syntax    
    TypeVarId -> TypeVar {cons("TypeVar")}

  context-free syntax
    Type "[" "]" -> ArrayType  {cons("ArrayType")}
