changeset 2166:257b779bc4c7

Implement type annotations for method and constructor reference type arguments.
author wmdietl
date Tue, 05 Feb 2013 15:55:17 -0600
parents 2de82c961dcc
children 48210e3920d6
files src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java
diffstat 3 files changed, 171 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Tue Feb 05 15:48:07 2013 -0600
+++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Tue Feb 05 15:55:17 2013 -0600
@@ -579,6 +579,10 @@
             System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
             System.out.println("    Framing tree: " + frame + " kind: " + frame.getKind());
             */
+
+            // Note that p.offset is set in
+            // com.sun.tools.javac.jvm.Gen.setTypeAnnotationPositions(int)
+
             switch (frame.getKind()) {
                 case TYPE_CAST:
                     p.type = TargetType.CAST;
@@ -663,6 +667,30 @@
                     return;
                 }
 
+                case MEMBER_REFERENCE: {
+                    if (((JCMemberReference)frame).typeargs.contains(tree)) {
+                        JCMemberReference mrframe = (JCMemberReference) frame;
+                        int arg = mrframe.typeargs.indexOf(tree);
+                        p.type_index = arg;
+                        switch (mrframe.mode) {
+                        case INVOKE:
+                            p.type = TargetType.METHOD_REFERENCE_TYPE_ARGUMENT;
+                            break;
+                        case NEW:
+                            p.type = TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
+                            break;
+                        default:
+                            Assert.error("Unknown method reference mode " + mrframe.mode +
+                                    " for tree " + tree + " within frame " + frame);
+                        }
+                        p.pos = frame.pos;
+                    } else {
+                        Assert.error("Could not determine type argument position of tree " + tree +
+                                " within frame " + frame);
+                    }
+                    return;
+                }
+
                 case ARRAY_TYPE: {
                     ListBuffer<TypePathEntry> index = ListBuffer.lb();
                     index = index.append(TypePathEntry.ARRAY);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java	Tue Feb 05 15:55:17 2013 -0600
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+/*
+ * @test
+ * @summary new type annotation location: lambda expressions
+ * @compile Lambda.java
+ * @author Werner Dietl
+ */
+public class Lambda {
+
+    interface LambdaInt {
+        <S, T> void generic(S p1, T p2);
+    }
+
+    static class LambdaImpl implements LambdaInt {
+        <S, T> LambdaImpl(S p1, T p2) {}
+        public <S, T> void generic(S p1, T p2) {}
+    }
+
+    LambdaInt getMethodRefTA(LambdaImpl r) {
+        return r::<@TA Object, @TB Object>generic;
+    }
+
+    LambdaInt getConstructorRefTA() {
+        return LambdaImpl::<@TA Object, @TB Object>new;
+    }
+
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TB { }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java	Tue Feb 05 15:55:17 2013 -0600
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
+
+/*
+ * @test
+ * @summary Test population of reference info for lambda expressions
+ * @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
+ * @run main Driver Lambda
+ * @author Werner Dietl
+ */
+public class Lambda {
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 0),
+        @TADescription(annotation = "TB", type = METHOD_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 1)
+    })
+    public String returnMethodRefTA1() {
+        return
+                "interface Lambda {" +
+                "  <S, T> void generic(S p1, T p2);" +
+                "}" +
+
+                "class LambdaImpl implements Lambda {" +
+                "  public <S, T> void generic(S p1, T p2) {}" +
+                "}" +
+
+                "class Test {" +
+                "  Lambda lambda(LambdaImpl r) {" +
+                "    return r::<@TA Object, @TB Object>generic;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 0),
+        @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 1)
+    })
+    public String returnConstructorRefTA2() {
+        return
+                "interface Lambda {" +
+                "  <S, T> void generic(S p1, T p2);" +
+                "}" +
+
+                "class LambdaImpl implements Lambda {" +
+                "  <S, T> LambdaImpl(S p1, T p2) {}" +
+                "  public <S, T> void generic(S p1, T p2) {}" +
+                "}" +
+
+                "class Test {" +
+                "  Lambda lambda() {" +
+                "    return LambdaImpl::<@TA Object, @TB Object>new;" +
+                "  }" +
+                "}";
+    }
+
+}