changeset 56970:1245f81d7e7c amber-demo-II

Automatic merge with records-and-sealed
author mcimadamore
date Mon, 05 Aug 2019 16:00:38 +0000
parents 49696396c60c 6974c8d6a7e0
children 1c00ffcef070
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
diffstat 6 files changed, 78 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/annotation/ElementType.java	Sat Aug 03 00:49:50 2019 +0000
+++ b/src/java.base/share/classes/java/lang/annotation/ElementType.java	Mon Aug 05 16:00:38 2019 +0000
@@ -114,5 +114,12 @@
      *
      * @since 9
      */
-    MODULE
+    MODULE,
+
+    /**
+     * Record component declaration
+     *
+     * @since amber
+     */
+    RECORD_COMPONENT
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Sat Aug 03 00:49:50 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Mon Aug 05 16:00:38 2019 +0000
@@ -201,7 +201,7 @@
         if (e.value.name == names.TYPE) {
             if (s.kind == TYP)
                 return AnnotationType.DECLARATION;
-        } else if (e.value.name == names.FIELD) {
+        } else if (e.value.name == names.FIELD || e.value.name == names.RECORD_COMPONENT) {
             if (s.kind == VAR &&
                     s.owner.kind != MTH)
                 return AnnotationType.DECLARATION;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Sat Aug 03 00:49:50 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Mon Aug 05 16:00:38 2019 +0000
@@ -117,7 +117,7 @@
 
         names = Names.instance(context);
         dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
-            names.FIELD, names.METHOD, names.CONSTRUCTOR,
+            names.FIELD, names.RECORD_COMPONENT, names.METHOD, names.CONSTRUCTOR,
             names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
         log = Log.instance(context);
         rs = Resolve.instance(context);
@@ -2855,16 +2855,18 @@
      */
     private void validateAnnotation(JCAnnotation a, JCTree declarationTree, Symbol s) {
         validateAnnotationTree(a);
+        boolean isRecordMember = s.isRecord() || s.enclClass() != null && s.enclClass().isRecord();
         if (debug) {
             System.out.println("validating annotations for tree " + declarationTree);
         }
 
-        if (s.isRecord() && s.flags_field == (Flags.PRIVATE | Flags.FINAL | Flags.MANDATED | Flags.RECORD) && declarationTree.hasTag(VARDEF)) {
+        if (isRecordMember &&
+                s.flags_field == (Flags.PRIVATE | Flags.FINAL | Flags.MANDATED | Flags.RECORD) && declarationTree.hasTag(VARDEF)) {
             // we are seeing a record field, which had the original annotations, now is the moment,
             // before stripping some of them just below, to check if the original annotations
             // applied to records at all, first version only cares about declaration annotations
             // we will add type annotations later on
-            Name[] targets = getTargetNames(a, s);
+            Name[] targets = getTargetNames(a);
             boolean appliesToRecords = false;
             for (Name target : targets) {
                 appliesToRecords =
@@ -2872,7 +2874,8 @@
                                 target == names.PARAMETER ||
                                 target == names.METHOD ||
                                 target == names.TYPE_USE ||
-                                target == names.TYPE_PARAMETER;
+                                target == names.TYPE_PARAMETER ||
+                                target == names.RECORD_COMPONENT;
                 if (appliesToRecords) {
                     break;
                 }
@@ -2887,7 +2890,7 @@
         if (a.type.tsym.isAnnotationType() && !annotationApplicable(a, s)) {
             // debug
             //System.out.println("at Check.validateAnnotation: flags: " + Flags.toString(s.flags_field) + ", declaration tree " + declarationTree);
-            if (s.isRecord() || s.owner.isRecord() && (s.flags_field & Flags.MANDATED) != 0) {
+            if (isRecordMember && (s.flags_field & Flags.MANDATED) != 0) {
                 JCModifiers modifiers = TreeInfo.getModifiers(declarationTree);
                 // lets first remove the annotation from the modifier
                 if (modifiers != null) {
@@ -3063,6 +3066,7 @@
             targets.add(names.ANNOTATION_TYPE);
             targets.add(names.CONSTRUCTOR);
             targets.add(names.FIELD);
+            targets.add(names.RECORD_COMPONENT);
             targets.add(names.LOCAL_VARIABLE);
             targets.add(names.METHOD);
             targets.add(names.PACKAGE);
@@ -3154,11 +3158,15 @@
         }
 
     /** Is the annotation applicable to the symbol? */
-    Name[] getTargetNames(JCAnnotation a, Symbol s) {
-        Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
+    Name[] getTargetNames(JCAnnotation a) {
+        return getTargetNames(a.annotationType.type.tsym);
+    }
+
+    public Name[] getTargetNames(TypeSymbol annoSym) {
+        Attribute.Array arr = getAttributeTargetAttribute(annoSym);
         Name[] targets;
         if (arr == null) {
-            targets = defaultTargetMetaInfo(a, s);
+            targets = defaultTargetMetaInfo();
         } else {
             // TODO: can we optimize this?
             targets = new Name[arr.values.length];
@@ -3175,7 +3183,7 @@
     }
 
     boolean annotationApplicable(JCAnnotation a, Symbol s) {
-        Name[] targets = getTargetNames(a, s);
+        Name[] targets = getTargetNames(a);
         if (targets.length == 0) {
             // recovery
             return true;
@@ -3184,7 +3192,7 @@
             if (target == names.TYPE) {
                 if (s.kind == TYP)
                     return true;
-            } else if (target == names.FIELD) {
+            } else if (target == names.FIELD || target == names.RECORD_COMPONENT) {
                 if (s.kind == VAR && s.owner.kind != MTH)
                     return true;
             } else if (target == names.METHOD) {
@@ -3240,7 +3248,7 @@
     }
 
     private final Name[] dfltTargetMeta;
-    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
+    private Name[] defaultTargetMetaInfo() {
         return dfltTargetMeta;
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Sat Aug 03 00:49:50 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Mon Aug 05 16:00:38 2019 +0000
@@ -26,10 +26,7 @@
 package com.sun.tools.javac.jvm;
 
 import java.io.*;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.LinkedHashSet;
+import java.util.*;
 
 import javax.tools.JavaFileManager;
 import javax.tools.FileObject;
@@ -49,6 +46,7 @@
 import com.sun.tools.javac.resources.CompilerProperties.Errors;
 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.List;
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.Kind.*;
@@ -345,13 +343,16 @@
     /** Write member (field or method) attributes;
      *  return number of attributes written.
      */
-    int writeMemberAttrs(Symbol sym) {
-        int acount = writeFlagAttrs(sym.flags());
+    int writeMemberAttrs(Symbol sym, boolean isRecordComponent) {
+        int acount = 0;
+        if (!isRecordComponent) {
+            acount = writeFlagAttrs(sym.flags());
+        }
         long flags = sym.flags();
         if ((flags & (SYNTHETIC | BRIDGE)) != SYNTHETIC &&
             (flags & ANONCONSTR) == 0 &&
             (!types.isSameType(sym.type, sym.erasure(types)) ||
-             poolWriter.signatureGen.hasTypeVar(sym.type.getThrownTypes()))) {
+            poolWriter.signatureGen.hasTypeVar(sym.type.getThrownTypes()))) {
             // note that a local class with captured variables
             // will get a signature attribute
             int alenIdx = writeAttr(names.Signature);
@@ -359,11 +360,27 @@
             endAttr(alenIdx);
             acount++;
         }
-        acount += writeJavaAnnotations(sym.getRawAttributes());
+        if (!isRecordComponent) {
+            acount += writeJavaAnnotations(sym.getRawAttributes().diff(extractRecordComponentAnnos(sym)));
+        } else {
+            acount += writeJavaAnnotations(extractRecordComponentAnnos(sym));
+        }
         acount += writeTypeAnnotations(sym.getRawTypeAttributes(), false);
         return acount;
     }
 
+    private List<Attribute.Compound> extractRecordComponentAnnos(Symbol sym) {
+        List<Attribute.Compound> annos = sym.getRawAttributes();
+        ListBuffer<Attribute.Compound> recordCompAnnosBuffer = new ListBuffer<>();
+        for (Attribute.Compound compound : annos) {
+            Name[] targetNames = check.getTargetNames(compound.type.tsym);
+            if (Arrays.stream(targetNames).filter(name -> name == names.RECORD_COMPONENT).findAny().isPresent()) {
+                recordCompAnnosBuffer.add(compound);
+            }
+        }
+        return recordCompAnnosBuffer.toList();
+    }
+
     /**
      * Write method parameter names attribute.
      */
@@ -403,7 +420,6 @@
             return 0;
     }
 
-
     private void writeParamAnnotations(List<VarSymbol> params,
                                        RetentionPolicy retention) {
         databuf.appendByte(params.length());
@@ -845,12 +861,22 @@
         }
         databuf.appendChar(numParams);
         for (VarSymbol v: vars) {
-            databuf.appendChar(poolWriter.putMember(v.accessors.head.snd));
+            //databuf.appendChar(poolWriter.putMember(v.accessors.head.snd));
+            writeComponentInfo(v);
         }
         endAttr(alenIdx);
         return 1;
     }
 
+    private void writeComponentInfo(VarSymbol v) {
+        databuf.appendChar(poolWriter.putName(v.name));
+        databuf.appendChar(poolWriter.putDescriptor(v));
+        int acountIdx = beginAttrs();
+        int acount = 0;
+        acount += writeMemberAttrs(v, true);
+        endAttrs(acountIdx, acount);
+    }
+
     /**
      * Write NestMembers attribute (if needed)
      */
@@ -956,7 +982,7 @@
             endAttr(alenIdx);
             acount++;
         }
-        acount += writeMemberAttrs(v);
+        acount += writeMemberAttrs(v, false);
         endAttrs(acountIdx, acount);
     }
 
@@ -1000,7 +1026,7 @@
             if (!m.isLambdaMethod()) // Per JDK-8138729, do not emit parameters table for lambda bodies.
                 acount += writeMethodParametersAttr(m);
         }
-        acount += writeMemberAttrs(m);
+        acount += writeMemberAttrs(m, false);
         if (!m.isLambdaMethod())
             acount += writeParameterAttrs(m.params);
         endAttrs(acountIdx, acount);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Sat Aug 03 00:49:50 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Mon Aug 05 16:00:38 2019 +0000
@@ -175,6 +175,7 @@
     public final Name TYPE;
     public final Name TYPE_PARAMETER;
     public final Name TYPE_USE;
+    public final Name RECORD_COMPONENT;
 
     // members of java.lang.annotation.RetentionPolicy
     public final Name CLASS;
@@ -346,6 +347,7 @@
         TYPE = fromString("TYPE");
         TYPE_PARAMETER = fromString("TYPE_PARAMETER");
         TYPE_USE = fromString("TYPE_USE");
+        RECORD_COMPONENT = fromString("RECORD_COMPONENT");
 
         // members of java.lang.annotation.RetentionPolicy
         CLASS = fromString("CLASS");
--- a/test/langtools/tools/javac/records/annotations/BadAnnotations.java	Sat Aug 03 00:49:50 2019 +0000
+++ b/test/langtools/tools/javac/records/annotations/BadAnnotations.java	Mon Aug 05 16:00:38 2019 +0000
@@ -33,24 +33,28 @@
     @interface Foo6 {}
     record R6(@Foo6 int i) {}
 
-    @Target({ ElementType.METHOD })
+    @Target({ ElementType.RECORD_COMPONENT })
     @interface Foo7 {}
     record R7(@Foo7 int i) {}
 
-    @Target({ ElementType.PARAMETER })
+    @Target({ ElementType.METHOD })
     @interface Foo8 {}
     record R8(@Foo8 int i) {}
 
-    // no target applies to all
+    @Target({ ElementType.PARAMETER })
     @interface Foo9 {}
     record R9(@Foo9 int i) {}
 
-    // type annotations are allowed too
-    @Target({ ElementType.TYPE_USE })
+    // no target applies to all
     @interface Foo10 {}
     record R10(@Foo10 int i) {}
 
-    @Target({ ElementType.TYPE_PARAMETER })
+    // type annotations are allowed too
+    @Target({ ElementType.TYPE_USE })
     @interface Foo11 {}
     record R11(@Foo11 int i) {}
+
+    @Target({ ElementType.TYPE_PARAMETER })
+    @interface Foo12 {}
+    record R12(@Foo12 int i) {}
 }