Hi Andrew,

Thanks for looking into this.  I'm totally guessing, but it may be that the 
problem is somewhere completely different than you are thinking.  In 
BinaryOperatorEmitter, there is already a "specialCaseDate" method that should 
have done the right thing, but I think that code was designed to handle 
compiling against SWF libraries and transpiling to AS and we've never dealt 
with compiling against JS libraries and transpiling.

For the first years of FlexJS we mainly compiled against SWF libraries and 
transpiled.  This is still allowed in Royale and works great if you are not 
using any SWF specific APIs.  Such a configuration uses playerglobal.swc or 
airglobal.swc.  Then Date. fullYear is defined, but the output in 
BinaryOperatorEmitter should get called and output getFullYear/setFullYear.  
Unless it broke recently.

It's only been the past year or so that we've got the "JS Only" configuration 
working where you compile against js.swc instead of playerglobal.  And I 
suspect that nobody has tried Date until you just did.  We could say that, if 
you are compiling against js.swc you are expected to use the APIs for the 
browser and can't use Date.fullYear, but because specialCaseDate already 
exists, we have the choice of adding Date.fullYear to the missing.js file in 
royale-typedefs/js/src/main/javascript.  Then I think you would be allowed to 
use Date.fullYear and it would get transpiled correctly.

I don't see any harm in adding SWF APIs to js.swc if we know how to transpile 
them.  What do others think?  It would be great if you could give that a try.

FWIW, this illustrates some of the pieces of the compiler.  Each source file as 
assigned a CompilationUnit.  The CompilationUnit built the parse tree.  The 
parsing phase doesn't really know much about what APIs are available so it 
correctly built the parse tree (AST).  Then, the CompilationUnit tries to 
reduce each AST to SWF byte code even if you only want JS output because the 
reduce has the semantic analysis code.  That's where the compiler realized that 
Date.fullYear was not defined in any source or library.  So I'm guessing you 
have to define it by adding it to js.swc.  Then once all APIs and dependencies 
have been found,  the output code like BinaryOperatorEmitter kicks in and 
outputs JS and looks for special cases like Date.fullYear and outputs 
Date.getFullYear/setFullYear instead.

HTH,
-Alex

On 6/28/18, 9:30 AM, "Frost, Andrew" <andrew.fr...@harman.com> wrote:

    Actually this will definitely need more effort/investigation, as this only 
helped with the ActionScript within my test MXML file (below); it didn't help 
when I had an assignment. So maybe the 'get' is sorted with the below but the 
'set' needs to be sorted within the MethodBodySemanticChecker.checkLValue() 
method?
    
    thanks
    
    ---
    Code from TextButton's click handler; compiles with my below hack:
       var tgt : TextButton = event.target as TextButton;
      var date : Date = new Date();
       if (tgt) tgt.text = "Thanks: " + date.toTimeString() + ".." + 
date.fullYear;
    
    Code that fails to compile still:
       date.fullYear = 2016;
    
    
    
    -----Original Message-----
    From: Frost, Andrew [mailto:andrew.fr...@harman.com] 
    Sent: 28 June 2018 17:04
    To: dev@royale.apache.org
    Subject: [EXTERNAL] Royale compiler not handling Date.fullYear etc
    
    Hi guys
    
    I'm getting errors with the Royale compiler when trying to access the 
properties of a Date object ("Error: Access of possibly undefined property 
fullYear through a reference with static type Date.")
    
    Having looked into it, this is because the JavaScript 'Date' object has 
"getFullYear" and "setFullYear", rather than set/get functions. There looks 
like there's some clever code going on within BinaryOperatorEmitter.java which 
should be able to handle this and translate the output (which it does, and 
which works fine), but we're getting the AccessUndefinedMemberProblem error 
reported prior to this.
    
    It looked to me as if there were a few possible workarounds for this, but I 
was thinking it might be better if someone a little more familiar with the 
compiler code was to look at this? I put in a hack within the 
"MethodBodySemanticChecker" class, in the "checkMemberAccess" method:
            IDefinition def = utils.getDefinition(member_node);
    
            // Is this a special case of "Date" where access to properties need 
to be functions?
            if ( (def == null) && (iNode instanceof MemberAccessExpressionNode) 
)
            {
                IExpressionNode left  = ((MemberAccessExpressionNode) 
iNode).getLeftOperandNode();
                IExpressionNode right = ((MemberAccessExpressionNode) 
iNode).getRightOperandNode();
                if (left instanceof IdentifierNode && right instanceof 
IdentifierNode)
                {
                      ITypeDefinition classLeft = left.resolveType(project);
                      if (classLeft != null && 
classLeft.getBaseName().equals("Date") )
                      {
                            // is the right hand side one of our acceptable 
elements?
                            String memberName = ((IdentifierNode) 
right).getName();
                            final String[] allowed = { "time", "fullYear", 
"month", "date", "fullYearUTC",
                                                                   "monthUTC", 
"dateUTC", "hours", "minutes", "seconds",
                                                                   
"milliseconds", "hoursUTC", "minutesUTC",
                                                                   
"secondsUTC","millisecondsUTF" };
                            if ( Arrays.asList(allowed).contains(memberName) ) 
return;
                      }
                }
            }
            if ( def == null && utils.definitionCanBeAnalyzed(member) )
            {
    
    This works - and the other BinaryOperatorEmitter code then kicks in to 
output the correct JavaScript - but it's not very elegant! and may screw up if 
anyone has created their own something.Date class .. so I was thinking it would 
be better to be fixed by an expert!
    
    Let me know if you'd like me to raise an issue on the royale-compiler 
github project for this..
    
    thanks
    
      Andrew
    
    

Reply via email to