test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java

Thu, 24 Oct 2013 16:52:27 -0700

author
rfield
date
Thu, 24 Oct 2013 16:52:27 -0700
changeset 2170
860f1d21763a
parent 1448
7d34e91f66bb
child 2174
62a67e0875ff
permissions
-rw-r--r--

8027220: DefaultMethodsTest: Change test to match spec
Reviewed-by: ksrini

     1 /*
     2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package org.openjdk.tests.separate;
    28 import java.util.*;
    29 import java.io.StringWriter;
    30 import java.io.PrintWriter;
    32 public class SourceModel {
    34     public static final String stdMethodName = "m";
    36     public static interface SourceProcessor {
    37         // Called with a generated source file
    38         void process(String name, String content);
    39     }
    41     public static abstract class Element {
    43         protected abstract void generate(PrintWriter pw);
    45         public String toString() {
    46             StringWriter sw = new StringWriter();
    47             PrintWriter pw = new PrintWriter(sw);
    48             generate(pw);
    49             return sw.toString();
    50         }
    51     };
    53     public static class AccessFlag extends Element {
    54         private String flag;
    56         public AccessFlag(String name) { flag = name; }
    58         protected void generate(PrintWriter pw) {
    59             pw.print(flag);
    60         }
    62         public String toString() { return flag; }
    64         public static final AccessFlag PUBLIC = new AccessFlag("public");
    65         public static final AccessFlag PRIVATE = new AccessFlag("private");
    66         public static final AccessFlag PROTECTED = new AccessFlag("protected");
    67         public static final AccessFlag STATIC = new AccessFlag("static");
    68         public static final AccessFlag FINAL = new AccessFlag("final");
    69         public static final AccessFlag SYNCHRONIZED = new AccessFlag("synchronized");
    70         public static final AccessFlag VOLATILE = new AccessFlag("volatile");
    71         public static final AccessFlag NATIVE = new AccessFlag("native");
    72         public static final AccessFlag ABSTRACT = new AccessFlag("abstract");
    73         public static final AccessFlag STRICTFP = new AccessFlag("strictfp");
    74         public static final AccessFlag DEFAULT = new AccessFlag("default");
    75     }
    77     public static class TypeParameter extends Element {
    78         private String parameter;
    80         public TypeParameter(String str) {
    81             this.parameter = str;
    82         }
    84         protected void generate(PrintWriter pw) {
    85             pw.print(parameter);
    86         }
    87     }
    89     public static class TypeArgument extends Element {
    90         private String argument;
    92         public TypeArgument(String str) {
    93             this.argument = str;
    94         }
    96         protected void generate(PrintWriter pw) {
    97             pw.print(argument);
    98         }
    99     }
   101     public static class MethodParameter extends Element {
   102         private String type;
   103         private String name;
   105         public MethodParameter(String type, String name) {
   106             this.type = type;
   107             this.name = name;
   108         }
   110         protected void generate(PrintWriter pw) {
   111             pw.printf("%s %s", this.type, this.name);
   112         }
   114         public String toString() { return type + " " + name; }
   115     }
   117     public static abstract class Type extends Element {
   118         private String name;
   119         private List<AccessFlag> accessFlags;
   120         private List<TypeParameter> parameters;
   121         private List<Extends> supertypes;
   122         private List<Method> methods;
   124         // methods from superclasses that are required for compilation
   125         // (and thus will be present in stubs)
   126         private Set<Method> methodDependencies;
   127         private List<Type> typeDependencies;
   129         protected Type(String name,
   130                 List<AccessFlag> flags, List<TypeParameter> params,
   131                 List<Extends> ifaces, List<Method> methods) {
   132             this.name = name;
   133             this.accessFlags = flags == null ? new ArrayList<>() : flags;
   134             this.parameters = params == null ? new ArrayList<>() : params;
   135             this.supertypes = ifaces == null ? new ArrayList<>() : ifaces;
   136             this.methods = methods == null ? new ArrayList<>() : methods;
   137             this.methodDependencies = new HashSet<>();
   138             this.typeDependencies = new ArrayList<>();
   139         }
   141         public String getName() { return this.name; }
   142         public List<AccessFlag> getAccessFlags() { return this.accessFlags; }
   143         public List<TypeParameter> getParameters() { return this.parameters; }
   144         public List<Extends> getSupertypes() { return this.supertypes; }
   145         public List<Method> getMethods() { return this.methods; }
   146         public Set<Method> methodDependencies() {
   147             return this.methodDependencies;
   148         }
   150         public Class getSuperclass() { return null; }
   151         protected abstract void setSuperClass(Extends supertype);
   153         public void addSuperType(Extends sup) {
   154             assert sup.getType() instanceof Interface : "Must be an interface";
   155             this.supertypes.add(sup);
   156         }
   157         public void addSuperType(Interface iface) {
   158             this.supertypes.add(new Extends(iface));
   159         }
   161         public void addMethod(Method m) {
   162             this.methods.add(m);
   163         }
   165         public void addAccessFlag(AccessFlag f) {
   166             this.accessFlags.add(f);
   167         }
   169         // Convenience method for creation.  Parameters are interpreted
   170         // according to their type.  Class (or Extends with a Class type) is
   171         // considered a superclass (only one allowed).  TypeParameters are
   172         // generic parameter names.  Interface (or Extends with an Interface
   173         // type) is an implemented supertype.  Methods are methods (duh!).
   174         protected void addComponent(Element p) {
   175             if (p instanceof Class) {
   176                 setSuperClass(new Extends((Class)p));
   177             } else if (p instanceof Extends) {
   178                 Extends ext = (Extends)p;
   179                 if (ext.supertype instanceof Class) {
   180                     setSuperClass(ext);
   181                 } else if (ext.supertype instanceof Interface) {
   182                     addSuperType(ext);
   183                 } else {
   184                     assert false : "What is this thing?";
   185                 }
   186             } else if (p instanceof Interface) {
   187                 addSuperType((Interface)p);
   188             } else if (p instanceof TypeParameter) {
   189                 this.parameters.add((TypeParameter)p);
   190             } else if (p instanceof Method) {
   191                 addMethod((Method)p);
   192             } else if (p instanceof AccessFlag) {
   193                 addAccessFlag((AccessFlag)p);
   194             } else {
   195                 assert false : "What is this thing?";
   196             }
   197         }
   199         // Find and return the first method that has name 'name'
   200         public Method findMethod(String name) {
   201             for (Method m : methods) {
   202                 if (m.name.equals(name)) {
   203                     return m;
   204                 }
   205             }
   206             return null;
   207         }
   209         public void addCompilationDependency(Type t) {
   210             typeDependencies.add(t);
   211         }
   213         public void addCompilationDependency(Method m) {
   214             methodDependencies.add(m);
   215         }
   217         // Convenience method for creating an Extends object using this
   218         // class and specified type arguments.
   219         public Extends with(String ... args) {
   220             return new Extends(this, args);
   221         }
   223         public abstract void generate(SourceProcessor sp);
   224         public abstract void generateAsDependency(
   225             SourceProcessor sp, Set<Method> neededMethods);
   227         protected void generateName(PrintWriter pw) {
   228             pw.print(this.name);
   229             toJoinedString(this.parameters, ",", "<", ">", "");
   230             pw.print(toJoinedString(this.parameters, ",", "<", ">", ""));
   231             pw.print(" ");
   232         }
   234         protected void generateBody(PrintWriter pw, String superSpec) {
   235             pw.print(toJoinedString(this.supertypes, ",", superSpec + " ", " ", ""));
   236             pw.println("{ ");
   237             pw.print(toJoinedString(this.methods, "\n    ", "\n    ", "\n", ""));
   238             pw.println("}");
   239         }
   241         protected void generateAccessFlags(PrintWriter pw) {
   242             pw.print(toJoinedString(this.accessFlags, " ", "", " "));
   243         }
   245         protected void generateBodyAsDependency(
   246             PrintWriter pw, Set<Method> neededMethods) {
   247             pw.println(" {");
   248             for (Method m : this.methods) {
   249                 if (neededMethods.contains(m)) {
   250                     pw.print("    ");
   251                     m.generate(pw);
   252                     pw.println();
   253                 }
   254             }
   255             pw.println("}");
   256         }
   258         public Collection<Type> typeDependencies() {
   259             HashMap<String,Type> dependencies = new HashMap<>();
   260             Type superclass = getSuperclass();
   261             if (superclass != null) {
   262                 dependencies.put(superclass.getName(), superclass);
   263             }
   264             for (Extends e : getSupertypes())
   265                 dependencies.put(e.getType().getName(), e.getType());
   266             // Do these last so that they override
   267             for (Type t : this.typeDependencies)
   268                 dependencies.put(t.getName(), t);
   269             return dependencies.values();
   270         }
   271     }
   273     public static class Class extends Type {
   274         private Extends superClass;
   276         public Class(String name, List<AccessFlag> flags,
   277                 List<TypeParameter> params, Extends sprClass,
   278                 List<Extends> interfaces, List<Method> methods) {
   279             super(name, flags, params, interfaces, methods);
   280             this.superClass = sprClass;
   281             addAccessFlag(AccessFlag.PUBLIC); // should remove this
   282         }
   284         public Class(String name, Element ... components) {
   285             super(name, null, null, null, null);
   286             this.superClass = null;
   288             for (Element p : components) {
   289                 addComponent(p);
   290             }
   291             addAccessFlag(AccessFlag.PUBLIC); // should remove this
   292         }
   294         public boolean isAbstract() {
   295             for (AccessFlag flag : getAccessFlags()) {
   296                 if (flag == AccessFlag.ABSTRACT) {
   297                     return true;
   298                 }
   299             }
   300             return false;
   301         }
   303         @Override
   304         public void setSuperClass(Extends ext) {
   305             assert this.superClass == null : "Multiple superclasses defined";
   306             assert ext.getType() instanceof Class : "Must be a class";
   307             this.superClass = ext;
   308         }
   310         public void setSuperClass(Class c) {
   311             setSuperClass(new Extends(c));
   312         }
   314         @Override
   315         public Class getSuperclass() {
   316             return superClass == null ? null : (Class)superClass.supertype;
   317         }
   319         public void generate(SourceProcessor processor) {
   320             StringWriter sw = new StringWriter();
   321             PrintWriter pw = new PrintWriter(sw);
   322             generate(pw);
   323             processor.process(getName(), sw.toString());
   324         }
   326         public void generate(PrintWriter pw) {
   327             generateAccessFlags(pw);
   328             pw.print("class ");
   329             generateName(pw);
   330             if (superClass != null) {
   331                 pw.print("extends ");
   332                 superClass.generate(pw);
   333                 pw.print(" ");
   334             }
   335             generateBody(pw, "implements");
   336         }
   338         public void generateAsDependency(
   339                 SourceProcessor processor, Set<Method> neededMethods) {
   340             StringWriter sw = new StringWriter();
   341             PrintWriter pw = new PrintWriter(sw);
   342             generateAccessFlags(pw);
   343             pw.print("class ");
   344             generateName(pw);
   345             pw.print(" ");
   346             generateBodyAsDependency(pw, neededMethods);
   348             processor.process(getName(), sw.toString());
   349         }
   350     }
   352     public static class Interface extends Type {
   354         public Interface(String name,
   355                   List<AccessFlag> flags, List<TypeParameter> params,
   356                   List<Extends> interfaces, List<Method> methods) {
   357             super(name, flags, params, interfaces, methods);
   358         }
   360         public Interface(String name, Element ... components) {
   361             super(name, null, null, null, null);
   362             for (Element c : components) {
   363                 addComponent(c);
   364             }
   365         }
   367         protected void setSuperClass(Extends ext) {
   368             assert false : "Interfaces cannot have Class supertypes";
   369         }
   371         public void generate(SourceProcessor processor) {
   372             StringWriter sw = new StringWriter();
   373             PrintWriter pw = new PrintWriter(sw);
   374             generate(pw);
   375             processor.process(getName(), sw.toString());
   376         }
   378         public void generate(PrintWriter pw) {
   379             generateAccessFlags(pw);
   380             pw.print("interface ");
   381             generateName(pw);
   382             pw.print(" ");
   383             generateBody(pw, "extends");
   384         }
   386         public void generateAsDependency(
   387                 SourceProcessor processor, Set<Method> neededMethods) {
   388             StringWriter sw = new StringWriter();
   389             PrintWriter pw = new PrintWriter(sw);
   391             generateAccessFlags(pw);
   392             pw.print("interface ");
   393             generateName(pw);
   394             pw.print(" ");
   395             generateBodyAsDependency(pw, neededMethods);
   397             processor.process(getName(), sw.toString());
   398         }
   399     }
   401     /**
   402      * Represents a type extension that might contain type arguments
   403      */
   404     public static class Extends extends Element {
   405         private final Type supertype;
   406         private final List<TypeArgument> arguments;
   408         public Type getType() { return supertype; }
   409         public List<TypeArgument> getArguments() {
   410             return arguments;
   411         }
   413         public Extends(Type supertype, String ... args) {
   414             assert supertype != null : "Null supertype";
   415             this.supertype = supertype;
   416             this.arguments = new ArrayList<>();
   417             for (String arg : args) {
   418                 this.arguments.add(new TypeArgument(arg));
   419             }
   420         }
   422         public void generate(PrintWriter pw) {
   423             pw.print(supertype.getName());
   424             pw.print(toJoinedString(getArguments(), ",", "<", ">", ""));
   425         }
   426     }
   428     public static abstract class Method extends Element {
   429         private String name;
   430         private String returnType;
   431         private List<AccessFlag> accessFlags;
   432         private List<MethodParameter> parameters;
   433         private boolean emitSuppressWarnings;
   435         protected Method(String ret, String name, Element ... params) {
   436             this.name = name;
   437             this.returnType = ret;
   438             this.accessFlags = new ArrayList<>();
   439             this.parameters = new ArrayList<>();
   440             this.emitSuppressWarnings = false;
   442             for (Element e : params) {
   443                 if (e instanceof MethodParameter) {
   444                     this.parameters.add((MethodParameter) e);
   445                 } else if (e instanceof AccessFlag) {
   446                     this.accessFlags.add((AccessFlag) e);
   447                 }
   448             }
   449             assert accessFlags.size() + parameters.size() == params.length :
   450                    "Non method parameters or access flags in constructor";
   451         }
   453         public String getName() { return this.name; }
   454         public String getReturnType() { return this.returnType; }
   455         public List<MethodParameter> getParameters() {
   456             return this.parameters;
   457         }
   458         public List<AccessFlag> getAccessFlags() {
   459             return this.accessFlags;
   460         }
   461         public Element[] getElements() {
   462             ArrayList<Element> elements = new ArrayList<>();
   463             elements.addAll(getParameters());
   464             elements.addAll(getAccessFlags());
   465             return elements.toArray(new Element[0]);
   466         }
   468         public void suppressWarnings() { this.emitSuppressWarnings = true; }
   470         public void generateWarningSuppression(PrintWriter pw) {
   471             if (this.emitSuppressWarnings) {
   472                 pw.printf("@SuppressWarnings(\"unchecked\")\n    ");
   473             }
   474         }
   476         protected void generateDecl(PrintWriter pw) {
   477             generateWarningSuppression(pw);
   478             pw.print(toJoinedString(this.accessFlags, " ", "", " "));
   479             pw.printf("%s %s(", returnType, name);
   480             pw.print(toJoinedString(parameters, ","));
   481             pw.print(")");
   482         }
   483     }
   485     public static class AbstractMethod extends Method {
   486         public AbstractMethod(
   487                 String ret, String name, Element ... params) {
   488             super(ret, name, params);
   489             this.getAccessFlags().add(AccessFlag.ABSTRACT);
   490         }
   492         public void generate(PrintWriter pw) {
   493             generateDecl(pw);
   494             pw.print(";");
   495         }
   497         public static AbstractMethod std() {
   498             return new AbstractMethod(
   499                 "int", SourceModel.stdMethodName, AccessFlag.PUBLIC);
   500         }
   501     }
   503     public static class ConcreteMethod extends Method {
   504         protected String body;
   506         public ConcreteMethod(String ret, String name,
   507                 String body, Element ... params) {
   508             super(ret, name, params);
   509             this.body = body;
   510         }
   512         public void generate(PrintWriter pw) {
   513             generateDecl(pw);
   514             pw.printf(" { %s }", this.body);
   515         }
   517         public static ConcreteMethod std(String value) {
   518             return new ConcreteMethod(
   519                 "int", SourceModel.stdMethodName, "return " + value + ";",
   520                 AccessFlag.PUBLIC);
   521         }
   522     }
   524     // When the default method flag gets moved into the traditional
   525     // access flags location, we can remove this class completely and
   526     // use a ConcreteMethod with an AccessFlag("default") in the constructor
   527     public static class DefaultMethod extends Method {
   528         protected String body;
   530         public DefaultMethod(String ret, String name, String body,
   531                 Element ... params) {
   532             super(ret, name, params);
   533             this.body = body;
   534             this.getAccessFlags().add(AccessFlag.DEFAULT);
   535         }
   537         public void generate(PrintWriter pw) {
   538             generateDecl(pw);
   539             pw.printf(" { %s }", this.body);
   540         }
   542         public static DefaultMethod std(String value) {
   543             return new DefaultMethod(
   544                 "int", SourceModel.stdMethodName, "return " + value + ";");
   545         }
   546     }
   548     private static <T> String toJoinedString(List<T> list, String... p) {
   549         StringBuilder sb = new StringBuilder();
   550         String sep = "";
   551         String init = "";
   552         String end = "";
   553         String empty = null;
   554         switch (p.length) {
   555             case 4:
   556                 empty = p[3];
   557             /*fall-through*/
   558             case 3:
   559                 end = p[2];
   560             /*fall-through*/
   561             case 2:
   562                 init = p[1];
   563             /*fall-through*/
   564             case 1:
   565                 sep = p[0];
   566                 break;
   567         }
   568         if (empty != null && list.isEmpty()) {
   569             return empty;
   570         } else {
   571             sb.append(init);
   572             for (T x : list) {
   573                 if (sb.length() != init.length()) {
   574                     sb.append(sep);
   575                 }
   576                 sb.append(x.toString());
   577             }
   578             sb.append(end);
   579             return sb.toString();
   580         }
   581     }
   582 }

mercurial