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