You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Lyuben Atanasov (Jira)" <ji...@apache.org> on 2023/11/13 16:08:00 UTC

[jira] [Created] (GROOVY-11222) Cannot parse methods that return types starting with lowercase letters

Lyuben Atanasov created GROOVY-11222:
----------------------------------------

             Summary: Cannot parse methods that return types starting with lowercase letters
                 Key: GROOVY-11222
                 URL: https://issues.apache.org/jira/browse/GROOVY-11222
             Project: Groovy
          Issue Type: Bug
          Components: parser
    Affects Versions: 4.0.15, 5.0.0-alpha-2
            Reporter: Lyuben Atanasov


According to the language specification, it is allowed to have class names that start with a lowercase letter:
{quote}Identifiers start with a letter, a dollar or an underscore. They cannot start with a number.

A letter can be in the following ranges:
 * 'a' to 'z' (lowercase ascii letter)

 * 'A' to 'Z' (uppercase ascii letter)

 * '\u00C0' to '\u00D6'

 * '\u00D8' to '\u00F6'

 * '\u00F8' to '\u00FF'

 * '\u0100' to '\uFFFE'{quote}
This is the same as in Java.

Defining types that start with lowercase letters works fine. As far as I can tell, I can also use such types as method arguments. What I cannot do, is to have methods that return types starting with lowercase letters.

Here's a failing example:
{code:groovy}
public class person {
    private String firstName;
    private String lastName;
    
    person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

public class PersonFactory {

    public person createPerson(String firstName, String lastName) {
        return new person(firstName, lastName);
    }
    
}
{code}
When parsing this code, it fails with the following error:
{noformat}
Script_b41cda4fe6804e170255542089871d79.groovy: 13: Unexpected input: '(' @ line 13, column 31.
       public person createPerson(String firstName, String lastName) {
                                 ^

1 error
{noformat}
If I change the class name to start with a capital letter, everything works:
{code:groovy}
public class Person {
    private String firstName;
    private String lastName;
    
    Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

public class PersonFactory {

    public Person createPerson(String firstName, String lastName) {
        return new Person(firstName, lastName);
    }
    
}
{code}
So it looks like there is a discrepancy between the language specification and the grammar definition. I looked into the grammar and managed to extract the following relevant lines from it, which should make the issue evident:
{code:java}
methodDeclaration[int t, int ct]
    :   modifiersOpt typeParameters? (returnType[$ct] nls)?
        methodName formalParameters
        (
            DEFAULT nls elementValue
        |
            (nls THROWS nls qualifiedClassNameList)?
            (nls methodBody)?
        )?
    ;
    
returnType[int ct]
    :
        standardType
    |   VOID
    ;
    
standardType
options { baseContext = type; }
    :   annotationsOpt
        (
            primitiveType
        |
            standardClassOrInterfaceType
        )
        emptyDimsOpt
    ;
    
standardClassOrInterfaceType
options { baseContext = classOrInterfaceType; }
    :   qualifiedStandardClassName typeArguments?
    ;
    
qualifiedStandardClassName
    :   qualifiedNameElements className (DOT className)*
    ;
    
className
    :   CapitalizedIdentifier
    ;
{code}
Here, it is allowed only to have a CapitalizedIdentifier as the class name. There is an obvious simple fix:
{code:java}
className
    :   CapitalizedIdentifier | Identifier
    ;
{code}
This should make the parser work in the same way as expected after reading the language spec. I am not sure, however, whether this won't break anything else.

In order to avoid any unnecessary discussions about naming conventions: I am aware that by convention it is not OK to start a type name with anything other than a capital letter, but there are valid cases where it is desired to have such names (e.g. generated code based on external input, DSLs).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)