001    /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.13-12-g880e696 */
002    package org.extendj.ast;
003    
004    import java.util.HashSet;
005    import java.io.File;
006    import java.util.Set;
007    import java.util.Collections;
008    import java.util.Collection;
009    import java.util.ArrayList;
010    import beaver.*;
011    import java.util.*;
012    import java.io.ByteArrayOutputStream;
013    import java.io.PrintStream;
014    import java.lang.reflect.InvocationTargetException;
015    import java.lang.reflect.Method;
016    import org.jastadd.util.*;
017    import java.util.zip.*;
018    import java.io.*;
019    import org.jastadd.util.PrettyPrintable;
020    import org.jastadd.util.PrettyPrinter;
021    import java.io.FileNotFoundException;
022    import java.io.BufferedInputStream;
023    import java.io.DataInputStream;
024    /**
025     * @ast node
026     * @declaredat /home/jesper/git/extendj/java8/grammar/ConstructorReference.ast:1
027     * @production ConstructorReference : {@link Expr} ::= <span class="component">TypeAccess:{@link Access}</span>;
028    
029     */
030    public abstract class ConstructorReference extends Expr implements Cloneable {
031      /**
032       * @aspect TypeCheck
033       * @declaredat /home/jesper/git/extendj/java8/frontend/TypeCheck.jrag:354
034       */
035      public void typeCheck() {
036        // 15.13.1
037        if (!assignmentContext() && !castContext() && !invocationContext()) {
038          error("Constructor references must target a functional interface");
039          return;
040        }
041    
042        // This means there was an error in the overload resolution, will be reported elsewhere
043        if (invocationContext() && targetType() == unknownType()) {
044          return;
045        }
046    
047        if (!targetType().isFunctionalInterface()) {
048          error("Constructor references must target a functional interface");
049          return;
050        }
051        InterfaceDecl iDecl = targetInterface();
052    
053        if (!iDecl.isFunctional()) {
054          errorf("Interface %s is not functional and can therefore not be targeted by a constructor reference",
055              iDecl.typeName());
056          return;
057        }
058    
059        FunctionDescriptor f = iDecl.functionDescriptor();
060    
061        if (this instanceof ClassReference) {
062          ClassReference ref = (ClassReference)this;
063          ConstructorDecl decl = ref.targetConstructor(f);
064          if (unknownConstructor() == decl) {
065            errorf("No constructor for the type %s that is compatible with the method %s in the interface %s was found",
066                getTypeAccess().type().typeName(), f.method.fullSignature(), iDecl.typeName());
067          }
068          if (!f.method.type().isVoid()) {
069            // 15.13.1
070            TypeDecl returnType = ref.syntheticInstanceExpr(f).type();
071            if (!returnType.assignConversionTo(f.method.type(), null)) {
072              errorf("Return type of method %s in interface %s is not compatible with"
073                  + " referenced constructor which has return type: %s",
074                  f.method.fullSignature(), iDecl.typeName(), returnType.typeName());
075            }
076          }
077          for (int i = 0; i < decl.getNumException(); i++) {
078            TypeDecl exception = decl.getException(i).type();
079            if (exception.isUncheckedException()) {
080              continue;
081            }
082    
083            boolean legalException = false;
084            for (TypeDecl descriptorThrows : iDecl.functionDescriptor().throwsList) {
085              if (exception.strictSubtype(descriptorThrows)) {
086                legalException = true;
087                break;
088              }
089            }
090            if (!legalException) {
091              // 15.13.1
092              errorf("Referenced constructor %s throws unhandled exception type %s",
093                  decl.name(), exception.typeName());
094            }
095          }
096          ref.syntheticInstanceExpr(f).typeCheck();
097        } else {
098          ArrayReference ref = (ArrayReference)this;
099          if (f.method.getNumParameter() != 1) {
100            errorf("Array reference not compatible with method %s in interface %s,"
101                + " should have a single parameter of type int",
102                f.method.fullSignature(), iDecl.typeName());
103            return;
104          }
105          if (!f.method.getParameter(0).type().assignConversionTo(iDecl.typeInt(), null)) {
106            errorf("Array reference not compatible with method %s in interface %s,"
107                + " should have a single parameter of type int",
108                f.method.fullSignature(), iDecl.typeName());
109            return;
110          }
111          if (!f.method.type().isVoid()) {
112            if (!getTypeAccess().type().assignConversionTo(f.method.type(), null)) {
113              errorf("Return type %s of method %s in interface %s is not compatible with"
114                  + " the array reference type %s",
115                  f.method.type().typeName(), f.method.fullSignature(), iDecl.typeName(),
116                  getTypeAccess().type().typeName());
117            }
118          }
119        }
120      }
121      /**
122       * @aspect Java8CreateBCode
123       * @declaredat /home/jesper/git/extendj/java8/backend/CreateBCode.jrag:41
124       */
125      public void createBCode(CodeGeneration gen) {
126        toClass().createBCode(gen);
127      }
128      /**
129       * @aspect Transformations
130       * @declaredat /home/jesper/git/extendj/java8/backend/Transformations.jrag:41
131       */
132      public void transformation() {
133        toClass().transformation();
134      }
135      /**
136       * @declaredat ASTNode:1
137       */
138      public ConstructorReference() {
139        super();
140      }
141      /**
142       * Initializes the child array to the correct size.
143       * Initializes List and Opt nta children.
144       * @apilevel internal
145       * @ast method
146       * @declaredat ASTNode:10
147       */
148      public void init$Children() {
149        children = new ASTNode[1];
150      }
151      /**
152       * @declaredat ASTNode:13
153       */
154      public ConstructorReference(Access p0) {
155        setChild(p0, 0);
156      }
157      /**
158       * @apilevel low-level
159       * @declaredat ASTNode:19
160       */
161      protected int numChildren() {
162        return 1;
163      }
164      /**
165       * @apilevel internal
166       * @declaredat ASTNode:25
167       */
168      public boolean mayHaveRewrite() {
169        return false;
170      }
171      /**
172       * @apilevel internal
173       * @declaredat ASTNode:31
174       */
175      public void flushAttrCache() {
176        super.flushAttrCache();
177        compatibleStrictContext_TypeDecl_reset();
178        compatibleLooseContext_TypeDecl_reset();
179        pertinentToApplicability_Expr_BodyDecl_int_reset();
180        moreSpecificThan_TypeDecl_TypeDecl_reset();
181        potentiallyCompatible_TypeDecl_BodyDecl_reset();
182        isPolyExpression_reset();
183        assignConversionTo_TypeDecl_reset();
184        targetInterface_reset();
185        type_reset();
186        toClass_reset();
187        toParameterList_reset();
188      }
189      /**
190       * @apilevel internal
191       * @declaredat ASTNode:48
192       */
193      public void flushCollectionCache() {
194        super.flushCollectionCache();
195      }
196      /**
197       * @apilevel internal
198       * @declaredat ASTNode:54
199       */
200      public void flushRewriteCache() {
201        super.flushRewriteCache();
202      }
203      /**
204       * @apilevel internal
205       * @declaredat ASTNode:60
206       */
207      public ConstructorReference clone() throws CloneNotSupportedException {
208        ConstructorReference node = (ConstructorReference) super.clone();
209        return node;
210      }
211      /**
212       * Create a deep copy of the AST subtree at this node.
213       * The copy is dangling, i.e. has no parent.
214       * @return dangling copy of the subtree at this node
215       * @apilevel low-level
216       * @deprecated Please use treeCopy or treeCopyNoTransform instead
217       * @declaredat ASTNode:71
218       */
219      @Deprecated
220      public abstract ConstructorReference fullCopy();
221      /**
222       * Create a deep copy of the AST subtree at this node.
223       * The copy is dangling, i.e. has no parent.
224       * @return dangling copy of the subtree at this node
225       * @apilevel low-level
226       * @declaredat ASTNode:79
227       */
228      public abstract ConstructorReference treeCopyNoTransform();
229      /**
230       * Create a deep copy of the AST subtree at this node.
231       * The subtree of this node is traversed to trigger rewrites before copy.
232       * The copy is dangling, i.e. has no parent.
233       * @return dangling copy of the subtree at this node
234       * @apilevel low-level
235       * @declaredat ASTNode:87
236       */
237      public abstract ConstructorReference treeCopy();
238      /**
239       * Replaces the TypeAccess child.
240       * @param node The new node to replace the TypeAccess child.
241       * @apilevel high-level
242       */
243      public void setTypeAccess(Access node) {
244        setChild(node, 0);
245      }
246      /**
247       * Retrieves the TypeAccess child.
248       * @return The current node used as the TypeAccess child.
249       * @apilevel high-level
250       */
251      @ASTNodeAnnotation.Child(name="TypeAccess")
252      public Access getTypeAccess() {
253        return (Access) getChild(0);
254      }
255      /**
256       * Retrieves the TypeAccess child.
257       * <p><em>This method does not invoke AST transformations.</em></p>
258       * @return The current node used as the TypeAccess child.
259       * @apilevel low-level
260       */
261      public Access getTypeAccessNoTransform() {
262        return (Access) getChildNoTransform(0);
263      }
264      /**
265       * @attribute syn
266       * @aspect ConstructorReference
267       * @declaredat /home/jesper/git/extendj/java8/frontend/ConstructorReference.jrag:68
268       */
269      @ASTNodeAnnotation.Attribute
270      public abstract boolean congruentTo(FunctionDescriptor f);
271      /**
272       * @attribute syn
273       * @aspect ConstructorReference
274       * @declaredat /home/jesper/git/extendj/java8/frontend/ConstructorReference.jrag:127
275       */
276      @ASTNodeAnnotation.Attribute
277      public abstract boolean isExact();
278      /**
279       * @attribute syn
280       * @aspect ConstructorReferenceToClass
281       * @declaredat /home/jesper/git/extendj/java8/backend/ConstructorReferenceToClass.jrag:85
282       */
283      @ASTNodeAnnotation.Attribute
284      public abstract Block toBlock();
285      /**
286       * @apilevel internal
287       */
288      protected java.util.Map compatibleStrictContext_TypeDecl_values;
289      /**
290       * @apilevel internal
291       */
292      private void compatibleStrictContext_TypeDecl_reset() {
293        compatibleStrictContext_TypeDecl_values = null;
294      }
295      /**
296       * @attribute syn
297       * @aspect MethodSignature18
298       * @declaredat /home/jesper/git/extendj/java8/frontend/MethodSignature.jrag:32
299       */
300      @ASTNodeAnnotation.Attribute
301      public boolean compatibleStrictContext(TypeDecl type) {
302        Object _parameters = type;
303        if (compatibleStrictContext_TypeDecl_values == null) compatibleStrictContext_TypeDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
304        ASTNode$State state = state();
305        if (compatibleStrictContext_TypeDecl_values.containsKey(_parameters)) {
306          return (Boolean) compatibleStrictContext_TypeDecl_values.get(_parameters);
307        }
308        boolean intermediate = state.INTERMEDIATE_VALUE;
309        state.INTERMEDIATE_VALUE = false;
310        int num = state.boundariesCrossed;
311        boolean isFinal = this.is$Final();
312        boolean compatibleStrictContext_TypeDecl_value = compatibleStrictContext_compute(type);
313        if (isFinal && num == state().boundariesCrossed) {
314          compatibleStrictContext_TypeDecl_values.put(_parameters, compatibleStrictContext_TypeDecl_value);
315        } else {
316        }
317        state.INTERMEDIATE_VALUE |= intermediate;
318    
319        return compatibleStrictContext_TypeDecl_value;
320      }
321      /**
322       * @apilevel internal
323       */
324      private boolean compatibleStrictContext_compute(TypeDecl type) {
325          if (!type.isFunctionalInterface()) {
326            return false;
327          }
328          InterfaceDecl iDecl = (InterfaceDecl) type;
329          return congruentTo(iDecl.functionDescriptor());
330        }
331      /**
332       * @apilevel internal
333       */
334      protected java.util.Map compatibleLooseContext_TypeDecl_values;
335      /**
336       * @apilevel internal
337       */
338      private void compatibleLooseContext_TypeDecl_reset() {
339        compatibleLooseContext_TypeDecl_values = null;
340      }
341      /**
342       * @attribute syn
343       * @aspect MethodSignature18
344       * @declaredat /home/jesper/git/extendj/java8/frontend/MethodSignature.jrag:79
345       */
346      @ASTNodeAnnotation.Attribute
347      public boolean compatibleLooseContext(TypeDecl type) {
348        Object _parameters = type;
349        if (compatibleLooseContext_TypeDecl_values == null) compatibleLooseContext_TypeDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
350        ASTNode$State state = state();
351        if (compatibleLooseContext_TypeDecl_values.containsKey(_parameters)) {
352          return (Boolean) compatibleLooseContext_TypeDecl_values.get(_parameters);
353        }
354        boolean intermediate = state.INTERMEDIATE_VALUE;
355        state.INTERMEDIATE_VALUE = false;
356        int num = state.boundariesCrossed;
357        boolean isFinal = this.is$Final();
358        boolean compatibleLooseContext_TypeDecl_value = compatibleStrictContext(type);
359        if (isFinal && num == state().boundariesCrossed) {
360          compatibleLooseContext_TypeDecl_values.put(_parameters, compatibleLooseContext_TypeDecl_value);
361        } else {
362        }
363        state.INTERMEDIATE_VALUE |= intermediate;
364    
365        return compatibleLooseContext_TypeDecl_value;
366      }
367      /**
368       * @apilevel internal
369       */
370      protected java.util.Map pertinentToApplicability_Expr_BodyDecl_int_values;
371      /**
372       * @apilevel internal
373       */
374      private void pertinentToApplicability_Expr_BodyDecl_int_reset() {
375        pertinentToApplicability_Expr_BodyDecl_int_values = null;
376      }
377      /**
378       * @attribute syn
379       * @aspect MethodSignature18
380       * @declaredat /home/jesper/git/extendj/java8/frontend/MethodSignature.jrag:107
381       */
382      @ASTNodeAnnotation.Attribute
383      public boolean pertinentToApplicability(Expr access, BodyDecl decl, int argIndex) {
384        java.util.List _parameters = new java.util.ArrayList(3);
385        _parameters.add(access);
386        _parameters.add(decl);
387        _parameters.add(argIndex);
388        if (pertinentToApplicability_Expr_BodyDecl_int_values == null) pertinentToApplicability_Expr_BodyDecl_int_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
389        ASTNode$State state = state();
390        if (pertinentToApplicability_Expr_BodyDecl_int_values.containsKey(_parameters)) {
391          return (Boolean) pertinentToApplicability_Expr_BodyDecl_int_values.get(_parameters);
392        }
393        boolean intermediate = state.INTERMEDIATE_VALUE;
394        state.INTERMEDIATE_VALUE = false;
395        int num = state.boundariesCrossed;
396        boolean isFinal = this.is$Final();
397        boolean pertinentToApplicability_Expr_BodyDecl_int_value = pertinentToApplicability_compute(access, decl, argIndex);
398        if (isFinal && num == state().boundariesCrossed) {
399          pertinentToApplicability_Expr_BodyDecl_int_values.put(_parameters, pertinentToApplicability_Expr_BodyDecl_int_value);
400        } else {
401        }
402        state.INTERMEDIATE_VALUE |= intermediate;
403    
404        return pertinentToApplicability_Expr_BodyDecl_int_value;
405      }
406      /**
407       * @apilevel internal
408       */
409      private boolean pertinentToApplicability_compute(Expr access, BodyDecl decl, int argIndex) {
410          if (!isExact()) {
411            return false;
412          }
413          if (decl instanceof MethodDecl
414              && decl.isGeneric()
415              && !(access instanceof ParMethodAccess)
416              && ((MethodDecl) decl).genericDecl().getParameter(argIndex).type().isTypeVariable()) {
417            GenericMethodDecl genericDecl = ((MethodDecl) decl).genericDecl();
418            TypeVariable typeVar = (TypeVariable) genericDecl.getParameter(argIndex).type();
419            for (int i = 0; i < genericDecl.getNumTypeParameter(); i++) {
420              if (typeVar == genericDecl.getTypeParameter(i)) {
421                return false;
422              }
423            }
424          } else if (decl instanceof ConstructorDecl
425              && decl.isGeneric()
426              && !(access instanceof ParConstructorAccess)
427              && !(access instanceof ParSuperConstructorAccess)
428              && !(access instanceof ParClassInstanceExpr)
429              && ((ConstructorDecl) decl).genericDecl().getParameter(argIndex).type().isTypeVariable()) {
430            GenericConstructorDecl genericDecl = ((ConstructorDecl) decl).genericDecl();
431            TypeVariable typeVar = (TypeVariable) genericDecl.getParameter(argIndex).type();
432            for (int i = 0; i < genericDecl.getNumTypeParameter(); i++) {
433              if (typeVar == genericDecl.getTypeParameter(i)) {
434                return false;
435              }
436            }
437          }
438          return true;
439        }
440      /**
441       * @apilevel internal
442       */
443      protected java.util.Map moreSpecificThan_TypeDecl_TypeDecl_values;
444      /**
445       * @apilevel internal
446       */
447      private void moreSpecificThan_TypeDecl_TypeDecl_reset() {
448        moreSpecificThan_TypeDecl_TypeDecl_values = null;
449      }
450      /**
451       * Computes which type is more specific for a specific argument, as defined in 15.12.2.5
452       * @param type1
453       * @param type2
454       * @return {@code true} if type1 is more specific than type2, {@code false} otherwise
455       * @attribute syn
456       * @aspect MethodSignature18
457       * @declaredat /home/jesper/git/extendj/java8/frontend/MethodSignature.jrag:233
458       */
459      @ASTNodeAnnotation.Attribute
460      public boolean moreSpecificThan(TypeDecl type1, TypeDecl type2) {
461        java.util.List _parameters = new java.util.ArrayList(2);
462        _parameters.add(type1);
463        _parameters.add(type2);
464        if (moreSpecificThan_TypeDecl_TypeDecl_values == null) moreSpecificThan_TypeDecl_TypeDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
465        ASTNode$State state = state();
466        if (moreSpecificThan_TypeDecl_TypeDecl_values.containsKey(_parameters)) {
467          return (Boolean) moreSpecificThan_TypeDecl_TypeDecl_values.get(_parameters);
468        }
469        boolean intermediate = state.INTERMEDIATE_VALUE;
470        state.INTERMEDIATE_VALUE = false;
471        int num = state.boundariesCrossed;
472        boolean isFinal = this.is$Final();
473        boolean moreSpecificThan_TypeDecl_TypeDecl_value = moreSpecificThan_compute(type1, type2);
474        if (isFinal && num == state().boundariesCrossed) {
475          moreSpecificThan_TypeDecl_TypeDecl_values.put(_parameters, moreSpecificThan_TypeDecl_TypeDecl_value);
476        } else {
477        }
478        state.INTERMEDIATE_VALUE |= intermediate;
479    
480        return moreSpecificThan_TypeDecl_TypeDecl_value;
481      }
482      /**
483       * @apilevel internal
484       */
485      private boolean moreSpecificThan_compute(TypeDecl type1, TypeDecl type2) {
486          if (super.moreSpecificThan(type1, type2)) {
487            return true;
488          }
489          if (!type1.isFunctionalInterface() || !type2.isFunctionalInterface()) {
490            return false;
491          }
492          if (type2.instanceOf(type1)) {
493            return false;
494          }
495          InterfaceDecl iDecl1 = (InterfaceDecl) type1;
496          InterfaceDecl iDecl2 = (InterfaceDecl) type2;
497      
498          if (!isExact()) {
499            return false;
500          }
501      
502          FunctionDescriptor f1 = iDecl1.functionDescriptor();
503          FunctionDescriptor f2 = iDecl2.functionDescriptor();
504      
505          if (f1.method.arity() != f2.method.arity()) {
506            return false;
507          }
508      
509          for (int i = 0; i < f1.method.getNumParameter(); i++) {
510            if (f1.method.getParameter(i).type() != f2.method.getParameter(i).type()) {
511              return false;
512            }
513          }
514      
515          // First bullet
516          if (f2.method.type().isVoid()) {
517            return true;
518          }
519      
520          // Second bullet
521          if (f1.method.type().instanceOf(f2.method.type())) {
522            return true;
523          }
524      
525          // Third bullet
526          if (f1.method.type().isPrimitiveType() && f2.method.type().isReferenceType()) {
527            // A constructor can never have primitive return type
528            return false;
529          }
530      
531          // Fourth bullet
532          if (f1.method.type().isReferenceType() && f2.method.type().isPrimitiveType()) {
533            // A constructor always have reference return type
534            return true;
535          }
536      
537          return false;
538      
539        }
540      /**
541       * @apilevel internal
542       */
543      protected java.util.Map potentiallyCompatible_TypeDecl_BodyDecl_values;
544      /**
545       * @apilevel internal
546       */
547      private void potentiallyCompatible_TypeDecl_BodyDecl_reset() {
548        potentiallyCompatible_TypeDecl_BodyDecl_values = null;
549      }
550      /**
551       * @attribute syn
552       * @aspect MethodSignature18
553       * @declaredat /home/jesper/git/extendj/java8/frontend/MethodSignature.jrag:466
554       */
555      @ASTNodeAnnotation.Attribute
556      public boolean potentiallyCompatible(TypeDecl type, BodyDecl candidateDecl) {
557        java.util.List _parameters = new java.util.ArrayList(2);
558        _parameters.add(type);
559        _parameters.add(candidateDecl);
560        if (potentiallyCompatible_TypeDecl_BodyDecl_values == null) potentiallyCompatible_TypeDecl_BodyDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
561        ASTNode$State state = state();
562        if (potentiallyCompatible_TypeDecl_BodyDecl_values.containsKey(_parameters)) {
563          return (Boolean) potentiallyCompatible_TypeDecl_BodyDecl_values.get(_parameters);
564        }
565        boolean intermediate = state.INTERMEDIATE_VALUE;
566        state.INTERMEDIATE_VALUE = false;
567        int num = state.boundariesCrossed;
568        boolean isFinal = this.is$Final();
569        boolean potentiallyCompatible_TypeDecl_BodyDecl_value = potentiallyCompatible_compute(type, candidateDecl);
570        if (isFinal && num == state().boundariesCrossed) {
571          potentiallyCompatible_TypeDecl_BodyDecl_values.put(_parameters, potentiallyCompatible_TypeDecl_BodyDecl_value);
572        } else {
573        }
574        state.INTERMEDIATE_VALUE |= intermediate;
575    
576        return potentiallyCompatible_TypeDecl_BodyDecl_value;
577      }
578      /**
579       * @apilevel internal
580       */
581      private boolean potentiallyCompatible_compute(TypeDecl type, BodyDecl candidateDecl) {
582          if (type.isTypeVariable()) {
583            if (candidateDecl.isGeneric()) {
584              boolean foundTypeVariable = false;
585              List<TypeVariable> typeParams = candidateDecl.typeParameters();
586              for (int i = 0; i < typeParams.getNumChild(); i++) {
587                if (type == typeParams.getChild(i)) {
588                  foundTypeVariable = true;
589                  break;
590                }
591              }
592              return foundTypeVariable;
593            } else {
594              return false;
595            }
596          }
597      
598          if (!type.isFunctionalInterface()) {
599            return false;
600          }
601          return true;
602        }
603      /**
604       * @apilevel internal
605       */
606      protected boolean isPolyExpression_computed = false;
607      /**
608       * @apilevel internal
609       */
610      protected boolean isPolyExpression_value;
611      /**
612       * @apilevel internal
613       */
614      private void isPolyExpression_reset() {
615        isPolyExpression_computed = false;
616      }
617      /**
618       * @attribute syn
619       * @aspect PolyExpressions
620       * @declaredat /home/jesper/git/extendj/java8/frontend/PolyExpressions.jrag:80
621       */
622      @ASTNodeAnnotation.Attribute
623      public boolean isPolyExpression() {
624        ASTNode$State state = state();
625        if (isPolyExpression_computed) {
626          return isPolyExpression_value;
627        }
628        boolean intermediate = state.INTERMEDIATE_VALUE;
629        state.INTERMEDIATE_VALUE = false;
630        int num = state.boundariesCrossed;
631        boolean isFinal = this.is$Final();
632        isPolyExpression_value = true;
633        if (isFinal && num == state().boundariesCrossed) {
634          isPolyExpression_computed = true;
635        } else {
636        }
637        state.INTERMEDIATE_VALUE |= intermediate;
638    
639        return isPolyExpression_value;
640      }
641      /**
642       * @apilevel internal
643       */
644      protected java.util.Map assignConversionTo_TypeDecl_values;
645      /**
646       * @apilevel internal
647       */
648      private void assignConversionTo_TypeDecl_reset() {
649        assignConversionTo_TypeDecl_values = null;
650      }
651      /**
652       * @attribute syn
653       * @aspect PolyExpressions
654       * @declaredat /home/jesper/git/extendj/java8/frontend/PolyExpressions.jrag:142
655       */
656      @ASTNodeAnnotation.Attribute
657      public boolean assignConversionTo(TypeDecl type) {
658        Object _parameters = type;
659        if (assignConversionTo_TypeDecl_values == null) assignConversionTo_TypeDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
660        ASTNode$State state = state();
661        if (assignConversionTo_TypeDecl_values.containsKey(_parameters)) {
662          return (Boolean) assignConversionTo_TypeDecl_values.get(_parameters);
663        }
664        boolean intermediate = state.INTERMEDIATE_VALUE;
665        state.INTERMEDIATE_VALUE = false;
666        int num = state.boundariesCrossed;
667        boolean isFinal = this.is$Final();
668        boolean assignConversionTo_TypeDecl_value = assignConversionTo_compute(type);
669        if (isFinal && num == state().boundariesCrossed) {
670          assignConversionTo_TypeDecl_values.put(_parameters, assignConversionTo_TypeDecl_value);
671        } else {
672        }
673        state.INTERMEDIATE_VALUE |= intermediate;
674    
675        return assignConversionTo_TypeDecl_value;
676      }
677      /**
678       * @apilevel internal
679       */
680      private boolean assignConversionTo_compute(TypeDecl type) {
681          if (!type.isFunctionalInterface()) {
682            return false;
683          }
684          FunctionDescriptor f = ((InterfaceDecl) type).functionDescriptor();
685          return congruentTo(f);
686        }
687      /**
688       * @apilevel internal
689       */
690      protected boolean targetInterface_computed = false;
691      /**
692       * @apilevel internal
693       */
694      protected InterfaceDecl targetInterface_value;
695      /**
696       * @apilevel internal
697       */
698      private void targetInterface_reset() {
699        targetInterface_computed = false;
700        targetInterface_value = null;
701      }
702      /**
703       * @attribute syn
704       * @aspect TargetType
705       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:162
706       */
707      @ASTNodeAnnotation.Attribute
708      public InterfaceDecl targetInterface() {
709        ASTNode$State state = state();
710        if (targetInterface_computed) {
711          return targetInterface_value;
712        }
713        boolean intermediate = state.INTERMEDIATE_VALUE;
714        state.INTERMEDIATE_VALUE = false;
715        int num = state.boundariesCrossed;
716        boolean isFinal = this.is$Final();
717        targetInterface_value = targetInterface_compute();
718        if (isFinal && num == state().boundariesCrossed) {
719          targetInterface_computed = true;
720        } else {
721        }
722        state.INTERMEDIATE_VALUE |= intermediate;
723    
724        return targetInterface_value;
725      }
726      /**
727       * @apilevel internal
728       */
729      private InterfaceDecl targetInterface_compute() {
730          if (targetType().isNull()) {
731            return null;
732          } else if (!(targetType() instanceof InterfaceDecl)) {
733            return null;
734          } else {
735            return (InterfaceDecl)targetType();
736          }
737        }
738      /**
739       * @apilevel internal
740       */
741      protected boolean type_computed = false;
742      /**
743       * @apilevel internal
744       */
745      protected TypeDecl type_value;
746      /**
747       * @apilevel internal
748       */
749      private void type_reset() {
750        type_computed = false;
751        type_value = null;
752      }
753      /**
754       * @attribute syn
755       * @aspect TypeCheck
756       * @declaredat /home/jesper/git/extendj/java8/frontend/TypeCheck.jrag:96
757       */
758      @ASTNodeAnnotation.Attribute
759      public TypeDecl type() {
760        ASTNode$State state = state();
761        if (type_computed) {
762          return type_value;
763        }
764        boolean intermediate = state.INTERMEDIATE_VALUE;
765        state.INTERMEDIATE_VALUE = false;
766        int num = state.boundariesCrossed;
767        boolean isFinal = this.is$Final();
768        type_value = type_compute();
769        if (isFinal && num == state().boundariesCrossed) {
770          type_computed = true;
771        } else {
772        }
773        state.INTERMEDIATE_VALUE |= intermediate;
774    
775        return type_value;
776      }
777      /**
778       * @apilevel internal
779       */
780      private TypeDecl type_compute() {
781          // 15.13.1
782          if (!assignmentContext() && !castContext() && !invocationContext()) {
783            return unknownType();
784          }
785          if (targetInterface() == null) {
786            return unknownType();
787          }
788      
789          InterfaceDecl iDecl = targetInterface();
790          if (!iDecl.isFunctional()) {
791            return unknownType();
792          }
793      
794          return iDecl;
795        }
796      /**
797       * @apilevel internal
798       */
799      protected boolean toClass_computed = false;
800      /**
801       * @apilevel internal
802       */
803      protected ClassInstanceExpr toClass_value;
804      /**
805       * @apilevel internal
806       */
807      private void toClass_reset() {
808        toClass_computed = false;
809        toClass_value = null;
810      }
811      /**
812       * @attribute syn
813       * @aspect ConstructorReferenceToClass
814       * @declaredat /home/jesper/git/extendj/java8/backend/ConstructorReferenceToClass.jrag:48
815       */
816      @ASTNodeAnnotation.Attribute
817      public ClassInstanceExpr toClass() {
818        ASTNode$State state = state();
819        if (toClass_computed) {
820          return toClass_value;
821        }
822        boolean intermediate = state.INTERMEDIATE_VALUE;
823        state.INTERMEDIATE_VALUE = false;
824        int num = state.boundariesCrossed;
825        boolean isFinal = this.is$Final();
826        toClass_value = toClass_compute();
827        toClass_value.setParent(this);
828        toClass_value.is$Final = true;
829        if (true) {
830          toClass_computed = true;
831        } else {
832        }
833        state.INTERMEDIATE_VALUE |= intermediate;
834    
835        return toClass_value;
836      }
837      /**
838       * @apilevel internal
839       */
840      private ClassInstanceExpr toClass_compute() {
841          List<Access> implementsList = new List<Access>();
842          InterfaceDecl iDecl = targetInterface();
843      
844          // First compute the interface implemented by the anonymous class
845          Access implementsInterface = iDecl.createQualifiedAccess();
846          implementsList.add(implementsInterface);
847      
848          // Next compute the BodyDecls for the anonymous class
849          List<BodyDecl> bodyDecls = new List<BodyDecl>();
850      
851          // Which means we must build the method overriding the abstract methods
852      
853          Modifiers methodModifiers = new Modifiers(new List<Modifier>().add(new Modifier("public")));
854          Access returnType = new SyntheticTypeAccess(iDecl.functionDescriptor().method.type());
855          List<ParameterDeclaration> methodParams = toParameterList();
856          List<Access> methodThrows = new List<Access>();
857          for (TypeDecl throwsType : iDecl.functionDescriptor().throwsList) {
858            methodThrows.add(new SyntheticTypeAccess(throwsType));
859          }
860          Opt<Block> methodBlock = new Opt<Block>(toBlock());
861          MethodDecl method = new MethodDecl(methodModifiers, returnType, iDecl.functionDescriptor().method.name(),
862                            methodParams, methodThrows, methodBlock);
863      
864          bodyDecls.add(method);
865      
866          /* Now the anonymous class can be built. Must use the type LambdaAnonymousDecl instead
867          of a normal AnonymousDecl in order for this and super keywords to get the type of the outer
868          scope. */
869          LambdaAnonymousDecl anonymousDecl = new LambdaAnonymousDecl(new Modifiers(), "ConstructorReference", bodyDecls);
870          for (Access impl: implementsList) {
871            anonymousDecl.addImplements(impl);
872          }
873      
874          return new ClassInstanceExpr((Access) implementsInterface.treeCopyNoTransform(), new List<Expr>(), new Opt<TypeDecl>(anonymousDecl));
875        }
876      /**
877       * @apilevel internal
878       */
879      protected boolean toParameterList_computed = false;
880      /**
881       * @apilevel internal
882       */
883      protected List<ParameterDeclaration> toParameterList_value;
884      /**
885       * @apilevel internal
886       */
887      private void toParameterList_reset() {
888        toParameterList_computed = false;
889        toParameterList_value = null;
890      }
891      /**
892       * @attribute syn
893       * @aspect ConstructorReferenceToClass
894       * @declaredat /home/jesper/git/extendj/java8/backend/ConstructorReferenceToClass.jrag:87
895       */
896      @ASTNodeAnnotation.Attribute
897      public List<ParameterDeclaration> toParameterList() {
898        ASTNode$State state = state();
899        if (toParameterList_computed) {
900          return toParameterList_value;
901        }
902        boolean intermediate = state.INTERMEDIATE_VALUE;
903        state.INTERMEDIATE_VALUE = false;
904        int num = state.boundariesCrossed;
905        boolean isFinal = this.is$Final();
906        toParameterList_value = toParameterList_compute();
907        if (isFinal && num == state().boundariesCrossed) {
908          toParameterList_computed = true;
909        } else {
910        }
911        state.INTERMEDIATE_VALUE |= intermediate;
912    
913        return toParameterList_value;
914      }
915      /**
916       * @apilevel internal
917       */
918      private List<ParameterDeclaration> toParameterList_compute() {
919          List<ParameterDeclaration> list = new List<ParameterDeclaration>();
920          for (int i = 0; i < targetInterface().functionDescriptor().method.getNumParameter(); i++) {
921            TypeDecl paramType = targetInterface().functionDescriptor().method.getParameter(i).type();
922            String paramName = targetInterface().functionDescriptor().method.getParameter(i).name();
923            list.add(new ParameterDeclaration(new SyntheticTypeAccess(paramType), paramName));
924          }
925          return list;
926        }
927      /**
928       * @attribute inh
929       * @aspect ConstructorReference
930       * @declaredat /home/jesper/git/extendj/java8/frontend/ConstructorReference.jrag:29
931       */
932      /**
933       * @attribute inh
934       * @aspect ConstructorReference
935       * @declaredat /home/jesper/git/extendj/java8/frontend/ConstructorReference.jrag:29
936       */
937      @ASTNodeAnnotation.Attribute
938      public ConstructorDecl unknownConstructor() {
939        ConstructorDecl unknownConstructor_value = getParent().Define_unknownConstructor(this, null);
940    
941        return unknownConstructor_value;
942      }
943      /**
944       * @declaredat /home/jesper/git/extendj/java4/frontend/SyntacticClassification.jrag:36
945       * @apilevel internal
946       */
947      public NameType Define_nameType(ASTNode caller, ASTNode child) {
948        if (caller == getTypeAccessNoTransform()) {
949          // @declaredat /home/jesper/git/extendj/java8/frontend/ConstructorReference.jrag:66
950          return NameType.TYPE_NAME;
951        }
952        else {
953          return getParent().Define_nameType(this, caller);
954        }
955      }
956      protected boolean canDefine_nameType(ASTNode caller, ASTNode child) {
957        return true;
958      }
959      /**
960       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:196
961       * @apilevel internal
962       */
963      public boolean Define_assignmentContext(ASTNode caller, ASTNode child) {
964        if (caller == getTypeAccessNoTransform()) {
965          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:397
966          return false;
967        }
968        else {
969          return getParent().Define_assignmentContext(this, caller);
970        }
971      }
972      protected boolean canDefine_assignmentContext(ASTNode caller, ASTNode child) {
973        return true;
974      }
975      /**
976       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:197
977       * @apilevel internal
978       */
979      public boolean Define_invocationContext(ASTNode caller, ASTNode child) {
980        if (caller == getTypeAccessNoTransform()) {
981          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:398
982          return false;
983        }
984        else {
985          return getParent().Define_invocationContext(this, caller);
986        }
987      }
988      protected boolean canDefine_invocationContext(ASTNode caller, ASTNode child) {
989        return true;
990      }
991      /**
992       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:198
993       * @apilevel internal
994       */
995      public boolean Define_castContext(ASTNode caller, ASTNode child) {
996        if (caller == getTypeAccessNoTransform()) {
997          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:399
998          return false;
999        }
1000        else {
1001          return getParent().Define_castContext(this, caller);
1002        }
1003      }
1004      protected boolean canDefine_castContext(ASTNode caller, ASTNode child) {
1005        return true;
1006      }
1007      /**
1008       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:199
1009       * @apilevel internal
1010       */
1011      public boolean Define_stringContext(ASTNode caller, ASTNode child) {
1012        if (caller == getTypeAccessNoTransform()) {
1013          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:400
1014          return false;
1015        }
1016        else {
1017          return getParent().Define_stringContext(this, caller);
1018        }
1019      }
1020      protected boolean canDefine_stringContext(ASTNode caller, ASTNode child) {
1021        return true;
1022      }
1023      /**
1024       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:200
1025       * @apilevel internal
1026       */
1027      public boolean Define_numericContext(ASTNode caller, ASTNode child) {
1028        if (caller == getTypeAccessNoTransform()) {
1029          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:401
1030          return false;
1031        }
1032        else {
1033          return getParent().Define_numericContext(this, caller);
1034        }
1035      }
1036      protected boolean canDefine_numericContext(ASTNode caller, ASTNode child) {
1037        return true;
1038      }
1039      /**
1040       * @apilevel internal
1041       */
1042      public ASTNode rewriteTo() {
1043        return super.rewriteTo();
1044      }
1045    }