Skip to content

Commit f0ec972

Browse files
authored
Separate PatternType from MethodType (openjdk#13)
* An experiment on PatternType. * Fixing test. * Fixing build. * Fixing tests. * Cleanup.
1 parent 77a1ffe commit f0ec972

File tree

14 files changed

+190
-46
lines changed

14 files changed

+190
-46
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Printer.java

+6
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ public String visitMethodType(MethodType t, Locale locale) {
250250
visit(t.restype, locale);
251251
}
252252

253+
@Override
254+
public String visitPatternType(PatternType t, Locale locale) {
255+
return "(" + printMethodArgs(t.bindingtypes, false, locale) + ")" +
256+
visit(t.restype, locale);
257+
}
258+
253259
@Override
254260
public String visitPackageType(PackageType t, Locale locale) {
255261
return t.tsym.getQualifiedName().toString();

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java

+113-9
Original file line numberDiff line numberDiff line change
@@ -285,15 +285,12 @@ protected boolean needsStripping() {
285285
@Override
286286
public Type visitMethodType(MethodType t, S s) {
287287
List<Type> argtypes = t.argtypes;
288-
List<Type> bindingtypes = t.bindingtypes;
289288
Type restype = t.restype;
290289
List<Type> thrown = t.thrown;
291-
List<Type> bindingtypes1 = bindingtypes != null ? visit(bindingtypes, s) : null;
292290
List<Type> argtypes1 = visit(argtypes, s);
293291
Type restype1 = visit(restype, s);
294292
List<Type> thrown1 = visit(thrown, s);
295293
if (argtypes1 == argtypes &&
296-
bindingtypes1 == bindingtypes &&
297294
restype1 == restype &&
298295
thrown1 == thrown) return t;
299296
else {
@@ -303,7 +300,6 @@ protected boolean needsStripping() {
303300
return true;
304301
}
305302
};
306-
methodType.bindingtypes = bindingtypes1;
307303
return methodType;
308304
}
309305
}
@@ -312,6 +308,22 @@ protected boolean needsStripping() {
312308
public Type visitForAll(ForAll t, S s) {
313309
return visit(t.qtype, s);
314310
}
311+
312+
@Override
313+
public Type visitPatternType(PatternType t, S s) {
314+
List<Type> bindingtypes = t.bindingtypes;
315+
List<Type> bindingtypes1 = visit(bindingtypes, s);
316+
if (bindingtypes1 == bindingtypes) return t;
317+
else {
318+
PatternType patternType = new PatternType(bindingtypes1, /*XXX*/t.restype, t.tsym) {
319+
@Override
320+
protected boolean needsStripping() {
321+
return true;
322+
}
323+
};
324+
return patternType;
325+
}
326+
}
315327
}
316328

317329
/** map a type function over all immediate descendants of this type
@@ -722,6 +734,8 @@ public static List<Type> filter(List<Type> ts, Predicate<Type> tf) {
722734
*/
723735
public MethodType asMethodType() { throw new AssertionError(); }
724736

737+
public PatternType asPatternType() { throw new AssertionError(); }
738+
725739
/** Complete loading all classes in this type.
726740
*/
727741
public void complete() {}
@@ -1479,7 +1493,6 @@ public <R, P> R accept(TypeVisitor<R, P> v, P p) {
14791493
public static class MethodType extends Type implements ExecutableType, LoadableConstant {
14801494

14811495
public List<Type> argtypes;
1482-
public List<Type> bindingtypes;
14831496
public Type restype;
14841497
public List<Type> thrown;
14851498

@@ -1528,7 +1541,7 @@ public String toString() {
15281541
public List<Type> getParameterTypes() { return argtypes; }
15291542

15301543
@DefinedBy(Api.LANGUAGE_MODEL)
1531-
public List<Type> getBindingTypes() { return bindingtypes; }
1544+
public List<Type> getBindingTypes() { return List.nil(); }
15321545

15331546
@DefinedBy(Api.LANGUAGE_MODEL)
15341547
public Type getReturnType() { return restype; }
@@ -1542,7 +1555,6 @@ public Type getReceiverType() {
15421555
public boolean isErroneous() {
15431556
return
15441557
isErroneous(argtypes) ||
1545-
bindingtypes != null && isErroneous(bindingtypes) ||
15461558
restype != null && restype.isErroneous();
15471559
}
15481560

@@ -1560,8 +1572,6 @@ public boolean contains(Type elem) {
15601572
public void complete() {
15611573
for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
15621574
l.head.complete();
1563-
for (List<Type> l = bindingtypes; l.nonEmpty(); l = l.tail)
1564-
l.head.complete();
15651575
restype.complete();
15661576
recvtype.complete();
15671577
for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
@@ -1923,6 +1933,99 @@ public <R, P> R accept(TypeVisitor<R, P> v, P p) {
19231933
}
19241934
}
19251935

1936+
public static class PatternType extends Type implements ExecutableType {
1937+
public List<Type> bindingtypes;
1938+
public Type restype;
1939+
1940+
public PatternType(List<Type> bindingtypes,
1941+
Type restype, //TODO:
1942+
TypeSymbol methodClass) {
1943+
super(methodClass, List.nil());
1944+
this.bindingtypes = bindingtypes;
1945+
this.restype = restype;
1946+
}
1947+
1948+
@Override
1949+
public TypeTag getTag() {
1950+
return TypeTag.PATTERN;
1951+
}
1952+
1953+
public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1954+
return v.visitPatternType(this, s);
1955+
}
1956+
1957+
/** The Java source which this type represents.
1958+
*
1959+
* XXX 06/09/99 iris This isn't correct Java syntax, but it probably
1960+
* should be.
1961+
*/
1962+
@DefinedBy(Api.LANGUAGE_MODEL)
1963+
public String toString() {
1964+
StringBuilder sb = new StringBuilder();
1965+
appendAnnotationsString(sb);
1966+
sb.append("(out");
1967+
sb.append(bindingtypes);
1968+
sb.append(')');
1969+
return sb.toString();
1970+
}
1971+
1972+
@DefinedBy(Api.LANGUAGE_MODEL)
1973+
public List<Type> getParameterTypes() { return List.nil(); }
1974+
1975+
@DefinedBy(Api.LANGUAGE_MODEL)
1976+
public List<Type> getBindingTypes() { return bindingtypes; }
1977+
1978+
@DefinedBy(Api.LANGUAGE_MODEL)
1979+
public Type getReturnType() { return restype; }
1980+
@DefinedBy(Api.LANGUAGE_MODEL)
1981+
public Type getReceiverType() {
1982+
return Type.noType;
1983+
}
1984+
@DefinedBy(Api.LANGUAGE_MODEL)
1985+
public List<Type> getThrownTypes() { return List.nil(); }
1986+
1987+
@Override
1988+
public PatternType asPatternType() { return this; }
1989+
1990+
public boolean isErroneous() {
1991+
return
1992+
bindingtypes != null && isErroneous(bindingtypes);
1993+
}
1994+
1995+
@Override
1996+
public int poolTag() {
1997+
return ClassFile.CONSTANT_MethodType; //TODO
1998+
}
1999+
2000+
public boolean contains(Type elem) {
2001+
return elem.equalsIgnoreMetadata(this);
2002+
}
2003+
2004+
public void complete() {
2005+
for (List<Type> l = bindingtypes; l.nonEmpty(); l = l.tail)
2006+
l.head.complete();
2007+
}
2008+
2009+
@DefinedBy(Api.LANGUAGE_MODEL)
2010+
public List<TypeVar> getTypeVariables() {
2011+
return List.nil();
2012+
}
2013+
2014+
public TypeSymbol asElement() {
2015+
return null;
2016+
}
2017+
2018+
@DefinedBy(Api.LANGUAGE_MODEL)
2019+
public TypeKind getKind() {
2020+
return TypeKind.EXECUTABLE;
2021+
}
2022+
2023+
@DefinedBy(Api.LANGUAGE_MODEL)
2024+
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2025+
return v.visitExecutable(this, p);
2026+
}
2027+
}
2028+
19262029
/** A class for inference variables, for use during method/diamond type
19272030
* inference. An inference variable has upper/lower bounds and a set
19282031
* of equality constraints. Such bounds are set during subtyping, type-containment,
@@ -2444,6 +2547,7 @@ public interface Visitor<R,S> {
24442547
R visitWildcardType(WildcardType t, S s);
24452548
R visitArrayType(ArrayType t, S s);
24462549
R visitMethodType(MethodType t, S s);
2550+
R visitPatternType(PatternType t, S s);
24472551
R visitPackageType(PackageType t, S s);
24482552
R visitModuleType(ModuleType t, S s);
24492553
R visitTypeVar(TypeVar t, S s);

src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java

+6
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,12 @@ public Type visitMethodType(MethodType t, List<TypeCompound> s) {
633633
return t;
634634
}
635635

636+
@Override
637+
public Type visitPatternType(Type.PatternType t, List<TypeCompound> s) {
638+
// Impossible?
639+
return t;
640+
}
641+
636642
@Override
637643
public Type visitPackageType(PackageType t, List<TypeCompound> s) {
638644
// Impossible?

src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeTag.java

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public enum TypeTag {
8484
/** The tag of all (monomorphic) method types.
8585
*/
8686
METHOD,
87+
PATTERN,
8788

8889
/** The tag of all package "types".
8990
*/

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java

+20-7
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,11 @@ public Boolean visitMethodType(MethodType t, Type s) {
14431443
return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
14441444
}
14451445

1446+
@Override
1447+
public Boolean visitPatternType(PatternType t, Type s) {
1448+
return hasSameArgs(t, s);
1449+
}
1450+
14461451
@Override
14471452
public Boolean visitPackageType(PackageType t, Type s) {
14481453
return t == s;
@@ -3299,12 +3304,16 @@ public Boolean visitType(Type t, Type s) {
32993304
@Override
33003305
public Boolean visitMethodType(MethodType t, Type s) {
33013306
if (s.hasTag(METHOD)) {
3302-
if (t.bindingtypes != null && t.bindingtypes.size() > 0) return containsTypeEquivalent(t.bindingtypes, s.getBindingTypes());
3303-
else return containsTypeEquivalent(t.argtypes, s.getParameterTypes());
3307+
return containsTypeEquivalent(t.argtypes, s.getParameterTypes());
33043308
}
33053309
return false;
33063310
}
33073311

3312+
@Override
3313+
public Boolean visitPatternType(PatternType t, Type s) {
3314+
return containsTypeEquivalent(t.bindingtypes, s.getBindingTypes());
3315+
}
3316+
33083317
@Override
33093318
public Boolean visitForAll(ForAll t, Type s) {
33103319
if (!s.hasTag(FORALL))
@@ -4941,6 +4950,7 @@ public abstract static class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S
49414950
public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
49424951
public R visitArrayType(ArrayType t, S s) { return visitType(t, s); }
49434952
public R visitMethodType(MethodType t, S s) { return visitType(t, s); }
4953+
public R visitPatternType(PatternType t, S s) { return visitType(t, s); }
49444954
public R visitPackageType(PackageType t, S s) { return visitType(t, s); }
49454955
public R visitModuleType(ModuleType t, S s) { return visitType(t, s); }
49464956
public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); }
@@ -5200,11 +5210,7 @@ public void assembleSig(Type type) {
52005210
case METHOD:
52015211
MethodType mt = (MethodType) type;
52025212
append('(');
5203-
if (mt.bindingtypes != null && mt.bindingtypes.size() > 0) {
5204-
assembleSig(mt.bindingtypes);
5205-
} else {
5206-
assembleSig(mt.argtypes);
5207-
}
5213+
assembleSig(mt.argtypes);
52085214
append(')');
52095215
assembleSig(mt.restype);
52105216
if (hasTypeVar(mt.thrown)) {
@@ -5214,6 +5220,13 @@ public void assembleSig(Type type) {
52145220
}
52155221
}
52165222
break;
5223+
case PATTERN:
5224+
PatternType pt = (PatternType) type;
5225+
append('(');
5226+
assembleSig(pt.bindingtypes);
5227+
append(')');
5228+
assembleSig(pt.restype);
5229+
break;
52175230
case WILDCARD: {
52185231
Type.WildcardType ta = (Type.WildcardType) type;
52195232
switch (ta.kind) {

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import static com.sun.tools.javac.code.Flags.*;
7575
import static com.sun.tools.javac.code.Flags.ANNOTATION;
7676
import static com.sun.tools.javac.code.Flags.BLOCK;
77+
import static com.sun.tools.javac.code.Flags.PATTERN;
7778
import static com.sun.tools.javac.code.Kinds.*;
7879
import static com.sun.tools.javac.code.Kinds.Kind.*;
7980
import static com.sun.tools.javac.code.TypeTag.*;
@@ -4592,9 +4593,8 @@ private List<MethodSymbol> patternDeclarationCandidatesWithArity(Type site, int
45924593
.map(rc -> types.memberType(site, rc))
45934594
.collect(List.collector());
45944595

4595-
MethodType mt = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);
4596-
mt.bindingtypes = recordComponents;
4597-
patternDeclarations = patternDeclarations.prepend(new MethodSymbol(PUBLIC | SYNTHETIC | PATTERN, ((ClassSymbol) site.tsym).name, mt, site.tsym));
4596+
PatternType pt = new PatternType(recordComponents, syms.voidType, syms.methodClass);
4597+
patternDeclarations = patternDeclarations.prepend(new MethodSymbol(PUBLIC | SYNTHETIC | PATTERN, ((ClassSymbol) site.tsym).name, pt, site.tsym));
45984598
}
45994599
}
46004600

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -3592,7 +3592,7 @@ public PatternDescription makePatternDescription(Type selectorType, JCPattern pa
35923592

35933593
MethodSymbol patternDeclaration = ((JCRecordPattern) pattern).patternDeclaration;
35943594
if (!record.type.isErroneous() && patternDeclaration != null) {
3595-
componentTypes = patternDeclaration.type.asMethodType().bindingtypes.toArray(Type[]::new);
3595+
componentTypes = patternDeclaration.type.asPatternType().bindingtypes.toArray(Type[]::new);
35963596
}
35973597
else {
35983598
componentTypes = record.nested.map(t -> types.createErrorType(t.type)).toArray(s -> new Type[s]);;

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -2653,12 +2653,12 @@ public void visitMethodDef(JCMethodDecl tree) {
26532653

26542654
m.params = m.params.prepend(implicitThisParam.sym);
26552655
Type olderasure = m.erasure(types);
2656+
//create an external type for the pattern:
26562657
var mt = new MethodType(
26572658
olderasure.getParameterTypes().prepend(tree.sym.owner.type),
26582659
olderasure.getReturnType(),
26592660
olderasure.getThrownTypes(),
26602661
syms.methodClass);
2661-
mt.bindingtypes = olderasure.getBindingTypes();
26622662

26632663
m.erasure_field = mt;
26642664
}

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java

+12-9
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,20 @@ Type signature(MethodSymbol msym,
156156
}
157157
thrownbuf.append(exc);
158158
}
159-
MethodType mtype = new MethodType(argbuf.toList(),
160-
restype,
161-
thrownbuf.toList(),
162-
syms.methodClass);
163-
if (bindings != null) {
164-
mtype.bindingtypes = bindingsbuf.toList();
165-
}
159+
if (msym.isPattern()) {
160+
Assert.check(params.isEmpty());
161+
return new PatternType(bindingsbuf.toList(), restype, syms.methodClass);
162+
} else {
163+
Assert.check(bindings == null);
164+
MethodType mtype = new MethodType(argbuf.toList(),
165+
restype,
166+
thrownbuf.toList(),
167+
syms.methodClass);
166168

167-
mtype.recvtype = recvtype;
169+
mtype.recvtype = recvtype;
168170

169-
return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
171+
return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
172+
}
170173
}
171174

172175
/* ********************************************************************

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ protected void read(Symbol sym, int attrLen) {
14061406

14071407
// todo: check if special handling is needed similar to generic methods for binding types
14081408

1409-
msym.type.asMethodType().bindingtypes = patternType.getParameterTypes();
1409+
msym.type = new PatternType(patternType.getParameterTypes(), syms.voidType, syms.methodClass);
14101410
}
14111411
}
14121412
},
@@ -2776,7 +2776,7 @@ MethodSymbol readMethod() {
27762776
}
27772777

27782778
void validateMethodType(Name name, Type t) {
2779-
if ((!t.hasTag(TypeTag.METHOD) && !t.hasTag(TypeTag.FORALL)) ||
2779+
if ((!t.hasTag(TypeTag.METHOD) && !t.hasTag(TypeTag.FORALL) && !t.hasTag(TypeTag.PATTERN)) ||
27802780
(name == names.init && !t.getReturnType().hasTag(TypeTag.VOID))) {
27812781
throw badClassFile("method.descriptor.invalid", name);
27822782
}

0 commit comments

Comments
 (0)