private AstNode propertyAccess ( int tt , AstNode pn ) throws IOException { if ( pn == null ) codeBug ( ) ; int memberTypeFlags = 0 , lineno = ts . lineno , dotPos = ts . tokenBeg ; consumeToken ( ) ; if ( tt == Token . DOTDOT ) { mustHaveXML ( ) ; memberTypeFlags = Node . DESCENDANTS_FLAG ; } if ( ! compilerEnv . isXmlAvailable ( ) ) { int maybeName = nextToken ( ) ; if ( maybeName != Token . NAME && ! ( compilerEnv . isReservedKeywordAsIdentifier ( ) && TokenStream . isKeyword ( ts . getString ( ) , compilerEnv . getLanguageVersion ( ) , inUseStrictDirective ) ) ) { reportError ( "msg.no.name.after.dot" ) ; } Name name = createNameNode ( true , Token . GETPROP ) ; PropertyGet pg = new PropertyGet ( pn , name , dotPos ) ; pg . setLineno ( lineno ) ; return pg ; } AstNode ref = null ; // right side of . or .. operator int token = nextToken ( ) ; switch ( token ) { case Token . THROW : // needed for generator.throw(); saveNameTokenData ( ts . tokenBeg , "throw" , ts . lineno ) ; ref = propertyName ( - 1 , "throw" , memberTypeFlags ) ; break ; case Token . NAME : // handles: name, ns::name, ns::*, ns::[expr] ref = propertyName ( - 1 , ts . getString ( ) , memberTypeFlags ) ; break ; case Token . MUL : // handles: *, *::name, *::*, *::[expr] saveNameTokenData ( ts . tokenBeg , "*" , ts . lineno ) ; ref = propertyName ( - 1 , "*" , memberTypeFlags ) ; break ; case Token . XMLATTR : // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*', // '@::attr', '@::*', '@*', '@*::attr', '@*::*' ref = attributeAccess ( ) ; break ; case Token . RESERVED : { String name = ts . getString ( ) ; saveNameTokenData ( ts . tokenBeg , name , ts . lineno ) ; ref = propertyName ( - 1 , name , memberTypeFlags ) ; break ; } default : if ( compilerEnv . isReservedKeywordAsIdentifier ( ) ) { // allow keywords as property names, e.g. ({if: 1}) String name = Token . keywordToName ( token ) ; if ( name != null ) { saveNameTokenData ( ts . tokenBeg , name , ts . lineno ) ; ref = propertyName ( - 1 , name , memberTypeFlags ) ; break ; } } reportError ( "msg.no.name.after.dot" ) ; return makeErrorNode ( ) ; } boolean xml = ref instanceof XmlRef ; InfixExpression result = xml ? new XmlMemberGet ( ) : new PropertyGet ( ) ; if ( xml && tt == Token . DOT ) result . setType ( Token . DOT ) ; int pos = pn . getPosition ( ) ; result . setPosition ( pos ) ; result . setLength ( getNodeEnd ( ref ) - pos ) ; result . setOperatorPosition ( dotPos - pos ) ; result . setLineno ( pn . getLineno ( ) ) ; result . setLeft ( pn ) ; // do this after setting position result . setRight ( ref ) ; return result ; }
Handles any construct following a . or .. operator .