-
Notifications
You must be signed in to change notification settings - Fork 5.2k
/
TypeMetadata.java
79 lines (71 loc) · 3.65 KB
/
TypeMetadata.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
* Copyright (c) 2014, 2023, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.javac.code;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
/**
* A type metadata is an object that can be stapled on a type. This is typically done using
* {@link Type#addMetadata(TypeMetadata)}. Metadata associated to a type can also be removed,
* typically using {@link Type#dropMetadata(Class)}. To drop <em>all</em> metadata from a given type,
* the {@link Type#baseType()} method can also be used. This can be useful when comparing two
* using reference equality (see also {@link Type#equalsIgnoreMetadata(Type)}).
* <p>
* There are no constraints on how a type metadata should be defined. Typically, a type
* metadata will be defined as a small record, storing additional information (see {@link ConstantValue}).
* In other cases, type metadata can be mutable and support complex state transitions
* (see {@link Annotations}).
* <p>
* The only invariant the implementation requires is that there must be <em>one</em> metadata
* of a given kind attached to a type, as this makes accessing and dropping metadata simpler.
* If clients wish to store multiple metadata values that are logically related, they should
* define a metadata type that collects such values in e.g. a list.
*/
public sealed interface TypeMetadata {
/**
* A type metadata object holding type annotations. This metadata needs to be mutable,
* because type annotations are sometimes set in two steps. That is, a type can be created with
* an empty set of annotations (e.g. during member enter). At some point later, the type
* is then updated to contain the correct annotations. At this point we need to augment
* the existing type (rather than creating a new one), as the type might already have been
* saved inside other symbols.
*/
record Annotations(ListBuffer<Attribute.TypeCompound> annotationBuffer) implements TypeMetadata {
Annotations() {
this(new ListBuffer<>());
}
Annotations(List<Attribute.TypeCompound> annotations) {
this();
annotationBuffer.appendList(annotations);
}
List<Attribute.TypeCompound> annotations() {
return annotationBuffer.toList();
}
}
/**
* A type metadata holding a constant value. This can be used to describe constant types,
* such as the type of a string literal, or that of a numeric constant.
*/
record ConstantValue(Object value) implements TypeMetadata { }
}