Name binding for class declarations with inheritance in Java is specified as follows:

ClassDec(ClassDecHead(m*, c, tp*, SuperDec(sc), _), body):
	defines Type c 
		of type RefType(TypeName(c), None())
		of kind Class()
		of modifiers m*
		of type-parameters tp*
	imports
		Field, imported Field, 
		Method, imported Method
		from Type sc
	implicitly defines Field "this" 
		of type RefType(TypeName(c), None())
		in body
	implicitly defines Field "super" 
		of type st
		in body
		where sc has type st
	scopes Type, TypeParam, Field, Method, Constructor

The implicit definitions are only defined in body to prevent access to this and super from outside this class.
However, this generates an anonymous scope for all definitions inside the body of a class, putting field and method declarations also in some anonymous scope. Because they are in an anonymous scope, fields and methods can never be accessed outside of this class, which is undesired.


For the example program:

package p;

class A {
	int a;
}

class B extends A {
	int b = a; // Resolution of a fails
}

the following definitions are stored in the index:

def / Type:"A"#0 / Package:"p" / DefaultPackage:Default() /
def / Type:"B"#0 / Package:"p" / DefaultPackage:Default() /
def / Field:"a"#0 / anon 0 / Type:"A"#0 / Package:"p" / DefaultPackage:Default() /
def / Field:"b"#0 / anon 0 / Type:"B"#0 / Package:"p" / DefaultPackage:Default() /
def / Field:"super"#0 / anon 3 /
def / Field:"this"#0 / anon 2 /
def / Field:"this"#0 / anon 1 /

The problem is that both field definitions have an anonymous scope. If I remove the in body part of the implicit definitions, this anonymous scope is not there.


For reference, here is the AST of the program:

File(
  CompilationUnit(
    "current"{ Def(
                 URI(
                   Language("Java")
                 , [ID(NablNsCompilationUnit(), "current", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0")), Anonymous("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0")]
                 )
               )
             }
  , []
  , DefaultPackageDec(
      Default(){Def(
                  URI(Language("Java"), [ID(NablNsDefaultPackage(), Default(), NonUnique())])
                )}
    , PackageDec(
        []
      , "p"{ Def(
               URI(
                 Language("Java")
               , [ID(NablNsPackage(), "p", NonUnique()), ID(NablNsDefaultPackage(), Default(), NonUnique())]
               )
             )
           }
      , [ ClassDec(
            ClassDecHead([Default()], "A"{ Def(
                                             URI(
                                               Language("Java")
                                             , [ ID(NablNsType(), "A", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0"))
                                               , ID(NablNsPackage(), "p", NonUnique())
                                               , ID(NablNsDefaultPackage(), Default(), NonUnique())
                                               ]
                                             )
                                           )
                                         }, None(), None(), None())
          , ClassBody([FieldDec([Default()], Int(){(Type(), Result(9))}, VarDec("a"{ Def(
                                                                                       URI(
                                                                                         Language("Java")
                                                                                       , [ ID(NablNsField(), "a", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0"))
                                                                                         , Anonymous("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0")
                                                                                         , ID(NablNsType(), "A", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0"))
                                                                                         , ID(NablNsPackage(), "p", NonUnique())
                                                                                         , ID(NablNsDefaultPackage(), Default(), NonUnique())
                                                                                         ]
                                                                                       )
                                                                                     )
                                                                                   }))]){ Scope(
                                                                                            [ ( NablNsField()
                                                                                              , URI(
                                                                                                  Language("Java")
                                                                                                , [ Anonymous("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0")
                                                                                                  , ID(NablNsType(), "A", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0"))
                                                                                                  , ID(NablNsPackage(), "p", NonUnique()){Barrier([NablNsPackage(), NablNsType()])}
                                                                                                  , ID(NablNsDefaultPackage(), Default(), NonUnique()){Barrier([NablNsPackage(), NablNsType()])}
                                                                                                  ]
                                                                                                )
                                                                                              )
                                                                                            ]
                                                                                          )
                                                                                        }
          )
        , ClassDec(
            ClassDecHead(
              [Default()]
            , "B"{ Def(
                     URI(
                       Language("Java")
                     , [ ID(NablNsType(), "B", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0"))
                       , ID(NablNsPackage(), "p", NonUnique())
                       , ID(NablNsDefaultPackage(), Default(), NonUnique())
                       ]
                     )
                   )
                 }
            , None()
            , SuperDec(ClassType(TypeName("A"{Use(Result(116))}){Use(Result(120)), (Type(), Result(46))}, None()){(Type(), Result(119))})
            , None()
            )
          , ClassBody(
              [FieldDec([Default()], Int(){(Type(), Result(9))}, VarDec("b"{ Def(
                                                                               URI(
                                                                                 Language("Java")
                                                                               , [ ID(NablNsField(), "b", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0"))
                                                                                 , Anonymous("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0")
                                                                                 , ID(NablNsType(), "B", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0"))
                                                                                 , ID(NablNsPackage(), "p", NonUnique())
                                                                                 , ID(NablNsDefaultPackage(), Default(), NonUnique())
                                                                                 ]
                                                                               )
                                                                             )
                                                                           }, ExprName("a"{Use(Result(75))}){(Type(), Result(79))}))]
            ){ Scope(
                 [ ( NablNsField()
                   , URI(
                       Language("Java")
                     , [ Anonymous("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0")
                       , ID(NablNsType(), "B", Unique("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0"))
                       , ID(NablNsPackage(), "p", NonUnique()){Barrier([NablNsPackage(), NablNsType()])}
                       , ID(NablNsDefaultPackage(), Default(), NonUnique()){Barrier([NablNsPackage(), NablNsType()])}
                       ]
                     )
                   )
                 ]
               )
             }
          )
        ]
      )
    )
  )
){ Scope(
     [(NablNsCompilationUnit(), URI(Language("Java"), [Anonymous("/Users/gohla/Spoofax/Workspaces/NBL/java-single-ex/test.jav/0")]))]
   )
 }
Submitted by Gabriël Konat on 19 March 2014 at 10:29

On 19 March 2014 at 10:33 Guido Wachsmuth commented:

Is this really a scope for all namespaces? If it is only for fields, this would make sense and could be avoided by putting this into a separate namespace. The annotation on the class body states only a scope for fields.


On 19 March 2014 at 11:16 Gabriël Konat commented:

You’re right, it’s only for fields, not for methods. I’ll work around it for now by putting this in a separate namespace. I still think this behavior would confuse users, is it possible to only generate an anonymous scope for the implicit definitions?


On 19 March 2014 at 11:29 Guido Wachsmuth commented:

I don’t think that this will fix it, since the behaviour is exactly the same for explicit definitions in scope. Each defines ... in t clause creates a scope at t. Why should this be different for implicit definitions?

You could also drop the in body part, and the definitions will still be scoped by the class declaration. However, this will import the implicit definitions into subclasses.

Log in to post comments