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

Tue, 24 Dec 2013 09:17:37 -0800

author
ksrini
date
Tue, 24 Dec 2013 09:17:37 -0800
changeset 2227
998b10c43157
parent 2174
62a67e0875ff
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8029230: Update copyright year to match last edit in jdk8 langtools repository for 2013
Reviewed-by: ksrini
Contributed-by: steve.sides@oracle.com

     1 /*
     2  * Copyright (c) 2012, 2013, 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;
   128         private boolean fullCompilation;
   130         protected Type(String name,
   131                 List<AccessFlag> flags, List<TypeParameter> params,
   132                 List<Extends> ifaces, List<Method> methods) {
   133             this.name = name;
   134             this.accessFlags = flags == null ? new ArrayList<>() : flags;
   135             this.parameters = params == null ? new ArrayList<>() : params;
   136             this.supertypes = ifaces == null ? new ArrayList<>() : ifaces;
   137             this.methods = methods == null ? new ArrayList<>() : methods;
   138             this.methodDependencies = new HashSet<>();
   139             this.typeDependencies = new ArrayList<>();
   140         }
   142         public String getName() { return this.name; }
   143         public List<AccessFlag> getAccessFlags() { return this.accessFlags; }
   144         public List<TypeParameter> getParameters() { return this.parameters; }
   145         public List<Extends> getSupertypes() { return this.supertypes; }
   146         public List<Method> getMethods() { return this.methods; }
   147         public Set<Method> methodDependencies() {
   148             return this.methodDependencies;
   149         }
   151         public Class getSuperclass() { return null; }
   152         protected abstract void setSuperClass(Extends supertype);
   154         public void addSuperType(Extends sup) {
   155             assert sup.getType() instanceof Interface : "Must be an interface";
   156             this.supertypes.add(sup);
   157         }
   158         public void addSuperType(Interface iface) {
   159             this.supertypes.add(new Extends(iface));
   160         }
   162         public void addMethod(Method m) {
   163             this.methods.add(m);
   164         }
   166         public void addAccessFlag(AccessFlag f) {
   167             this.accessFlags.add(f);
   168         }
   170         // Convenience method for creation.  Parameters are interpreted
   171         // according to their type.  Class (or Extends with a Class type) is
   172         // considered a superclass (only one allowed).  TypeParameters are
   173         // generic parameter names.  Interface (or Extends with an Interface
   174         // type) is an implemented supertype.  Methods are methods (duh!).
   175         protected void addComponent(Element p) {
   176             if (p instanceof Class) {
   177                 setSuperClass(new Extends((Class)p));
   178             } else if (p instanceof Extends) {
   179                 Extends ext = (Extends)p;
   180                 if (ext.supertype instanceof Class) {
   181                     setSuperClass(ext);
   182                 } else if (ext.supertype instanceof Interface) {
   183                     addSuperType(ext);
   184                 } else {
   185                     assert false : "What is this thing?";
   186                 }
   187             } else if (p instanceof Interface) {
   188                 addSuperType((Interface)p);
   189             } else if (p instanceof TypeParameter) {
   190                 this.parameters.add((TypeParameter)p);
   191             } else if (p instanceof Method) {
   192                 addMethod((Method)p);
   193             } else if (p instanceof AccessFlag) {
   194                 addAccessFlag((AccessFlag)p);
   195             } else {
   196                 assert false : "What is this thing?";
   197             }
   198         }
   200         // Find and return the first method that has name 'name'
   201         public Method findMethod(String name) {
   202             for (Method m : methods) {
   203                 if (m.name.equals(name)) {
   204                     return m;
   205                 }
   206             }
   207             return null;
   208         }
   210         public void addCompilationDependency(Type t) {
   211             typeDependencies.add(t);
   212         }
   214         public void addCompilationDependency(Method m) {
   215             methodDependencies.add(m);
   216         }
   218         public boolean isFullCompilation() {
   219             return fullCompilation;
   220         }
   222         public void setFullCompilation(boolean fullCompilation) {
   223             this.fullCompilation = fullCompilation;
   224         }
   226         // Convenience method for creating an Extends object using this
   227         // class and specified type arguments.
   228         public Extends with(String ... args) {
   229             return new Extends(this, args);
   230         }
   232         public abstract void generate(SourceProcessor sp);
   233         public abstract void generateAsDependency(
   234             SourceProcessor sp, Set<Method> neededMethods);
   236         protected void generateName(PrintWriter pw) {
   237             pw.print(this.name);
   238             toJoinedString(this.parameters, ",", "<", ">", "");
   239             pw.print(toJoinedString(this.parameters, ",", "<", ">", ""));
   240             pw.print(" ");
   241         }
   243         protected void generateBody(PrintWriter pw, String superSpec) {
   244             pw.print(toJoinedString(this.supertypes, ",", superSpec + " ", " ", ""));
   245             pw.println("{ ");
   246             pw.print(toJoinedString(this.methods, "\n    ", "\n    ", "\n", ""));
   247             pw.println("}");
   248         }
   250         protected void generateAccessFlags(PrintWriter pw) {
   251             pw.print(toJoinedString(this.accessFlags, " ", "", " "));
   252         }
   254         protected void generateBodyAsDependency(
   255             PrintWriter pw, Set<Method> neededMethods) {
   256             pw.println(" {");
   257             for (Method m : this.methods) {
   258                 if (neededMethods.contains(m)) {
   259                     pw.print("    ");
   260                     m.generate(pw);
   261                     pw.println();
   262                 }
   263             }
   264             pw.println("}");
   265         }
   267         public Collection<Type> typeDependencies(boolean recursive) {
   268             HashMap<String,Type> dependencies = new HashMap<>();
   269             Type superclass = getSuperclass();
   270             if (superclass != null) {
   271                 dependencies.put(superclass.getName(), superclass);
   272                 if (recursive) {
   273                     for (Type t : superclass.typeDependencies(true))
   274                         dependencies.put(t.getName(), t);
   275                 }
   276             }
   277             for (Extends e : getSupertypes()) {
   278                 dependencies.put(e.getType().getName(), e.getType());
   279                 if (recursive) {
   280                     for (Type t : e.getType().typeDependencies(true))
   281                         dependencies.put(t.getName(), t);
   282                 }
   283             }
   284             // Do these last so that they override
   285             for (Type t : this.typeDependencies)
   286                 dependencies.put(t.getName(), t);
   287             return dependencies.values();
   288         }
   289     }
   291     public static class Class extends Type {
   292         private Extends superClass;
   294         public Class(String name, List<AccessFlag> flags,
   295                 List<TypeParameter> params, Extends sprClass,
   296                 List<Extends> interfaces, List<Method> methods) {
   297             super(name, flags, params, interfaces, methods);
   298             this.superClass = sprClass;
   299             addAccessFlag(AccessFlag.PUBLIC); // should remove this
   300         }
   302         public Class(String name, Element ... components) {
   303             super(name, null, null, null, null);
   304             this.superClass = null;
   306             for (Element p : components) {
   307                 addComponent(p);
   308             }
   309             addAccessFlag(AccessFlag.PUBLIC); // should remove this
   310         }
   312         public boolean isAbstract() {
   313             for (AccessFlag flag : getAccessFlags()) {
   314                 if (flag == AccessFlag.ABSTRACT) {
   315                     return true;
   316                 }
   317             }
   318             return false;
   319         }
   321         @Override
   322         public void setSuperClass(Extends ext) {
   323             assert this.superClass == null : "Multiple superclasses defined";
   324             assert ext.getType() instanceof Class : "Must be a class";
   325             this.superClass = ext;
   326         }
   328         public void setSuperClass(Class c) {
   329             setSuperClass(new Extends(c));
   330         }
   332         @Override
   333         public Class getSuperclass() {
   334             return superClass == null ? null : (Class)superClass.supertype;
   335         }
   337         public void generate(SourceProcessor processor) {
   338             StringWriter sw = new StringWriter();
   339             PrintWriter pw = new PrintWriter(sw);
   340             generate(pw);
   341             processor.process(getName(), sw.toString());
   342         }
   344         public void generate(PrintWriter pw) {
   345             generateAccessFlags(pw);
   346             pw.print("class ");
   347             generateName(pw);
   348             if (superClass != null) {
   349                 pw.print("extends ");
   350                 superClass.generate(pw);
   351                 pw.print(" ");
   352             }
   353             generateBody(pw, "implements");
   354         }
   356         public void generateAsDependency(
   357                 SourceProcessor processor, Set<Method> neededMethods) {
   358             StringWriter sw = new StringWriter();
   359             PrintWriter pw = new PrintWriter(sw);
   360             generateAccessFlags(pw);
   361             pw.print("class ");
   362             generateName(pw);
   363             pw.print(" ");
   364             generateBodyAsDependency(pw, neededMethods);
   366             processor.process(getName(), sw.toString());
   367         }
   368     }
   370     public static class Interface extends Type {
   372         public Interface(String name,
   373                   List<AccessFlag> flags, List<TypeParameter> params,
   374                   List<Extends> interfaces, List<Method> methods) {
   375             super(name, flags, params, interfaces, methods);
   376         }
   378         public Interface(String name, Element ... components) {
   379             super(name, null, null, null, null);
   380             for (Element c : components) {
   381                 addComponent(c);
   382             }
   383         }
   385         protected void setSuperClass(Extends ext) {
   386             assert false : "Interfaces cannot have Class supertypes";
   387         }
   389         public void generate(SourceProcessor processor) {
   390             StringWriter sw = new StringWriter();
   391             PrintWriter pw = new PrintWriter(sw);
   392             generate(pw);
   393             processor.process(getName(), sw.toString());
   394         }
   396         public void generate(PrintWriter pw) {
   397             generateAccessFlags(pw);
   398             pw.print("interface ");
   399             generateName(pw);
   400             pw.print(" ");
   401             generateBody(pw, "extends");
   402         }
   404         public void generateAsDependency(
   405                 SourceProcessor processor, Set<Method> neededMethods) {
   406             StringWriter sw = new StringWriter();
   407             PrintWriter pw = new PrintWriter(sw);
   409             generateAccessFlags(pw);
   410             pw.print("interface ");
   411             generateName(pw);
   412             pw.print(" ");
   413             generateBodyAsDependency(pw, neededMethods);
   415             processor.process(getName(), sw.toString());
   416         }
   417     }
   419     /**
   420      * Represents a type extension that might contain type arguments
   421      */
   422     public static class Extends extends Element {
   423         private final Type supertype;
   424         private final List<TypeArgument> arguments;
   426         public Type getType() { return supertype; }
   427         public List<TypeArgument> getArguments() {
   428             return arguments;
   429         }
   431         public Extends(Type supertype, String ... args) {
   432             assert supertype != null : "Null supertype";
   433             this.supertype = supertype;
   434             this.arguments = new ArrayList<>();
   435             for (String arg : args) {
   436                 this.arguments.add(new TypeArgument(arg));
   437             }
   438         }
   440         public void generate(PrintWriter pw) {
   441             pw.print(supertype.getName());
   442             pw.print(toJoinedString(getArguments(), ",", "<", ">", ""));
   443         }
   444     }
   446     public static abstract class Method extends Element {
   447         private String name;
   448         private String returnType;
   449         private List<AccessFlag> accessFlags;
   450         private List<MethodParameter> parameters;
   451         private boolean emitSuppressWarnings;
   453         protected Method(String ret, String name, Element ... params) {
   454             this.name = name;
   455             this.returnType = ret;
   456             this.accessFlags = new ArrayList<>();
   457             this.parameters = new ArrayList<>();
   458             this.emitSuppressWarnings = false;
   460             for (Element e : params) {
   461                 if (e instanceof MethodParameter) {
   462                     this.parameters.add((MethodParameter) e);
   463                 } else if (e instanceof AccessFlag) {
   464                     this.accessFlags.add((AccessFlag) e);
   465                 }
   466             }
   467             assert accessFlags.size() + parameters.size() == params.length :
   468                    "Non method parameters or access flags in constructor";
   469         }
   471         public String getName() { return this.name; }
   472         public String getReturnType() { return this.returnType; }
   473         public List<MethodParameter> getParameters() {
   474             return this.parameters;
   475         }
   476         public List<AccessFlag> getAccessFlags() {
   477             return this.accessFlags;
   478         }
   479         public Element[] getElements() {
   480             ArrayList<Element> elements = new ArrayList<>();
   481             elements.addAll(getParameters());
   482             elements.addAll(getAccessFlags());
   483             return elements.toArray(new Element[0]);
   484         }
   486         public void suppressWarnings() { this.emitSuppressWarnings = true; }
   488         public void generateWarningSuppression(PrintWriter pw) {
   489             if (this.emitSuppressWarnings) {
   490                 pw.printf("@SuppressWarnings(\"unchecked\")\n    ");
   491             }
   492         }
   494         protected void generateDecl(PrintWriter pw) {
   495             generateWarningSuppression(pw);
   496             pw.print(toJoinedString(this.accessFlags, " ", "", " "));
   497             pw.printf("%s %s(", returnType, name);
   498             pw.print(toJoinedString(parameters, ","));
   499             pw.print(")");
   500         }
   501     }
   503     public static class AbstractMethod extends Method {
   504         public AbstractMethod(
   505                 String ret, String name, Element ... params) {
   506             super(ret, name, params);
   507             this.getAccessFlags().add(AccessFlag.ABSTRACT);
   508         }
   510         public void generate(PrintWriter pw) {
   511             generateDecl(pw);
   512             pw.print(";");
   513         }
   515         public static AbstractMethod std() {
   516             return new AbstractMethod(
   517                 "int", SourceModel.stdMethodName, AccessFlag.PUBLIC);
   518         }
   519     }
   521     public static class ConcreteMethod extends Method {
   522         protected String body;
   524         public ConcreteMethod(String ret, String name,
   525                 String body, Element ... params) {
   526             super(ret, name, params);
   527             this.body = body;
   528         }
   530         public void generate(PrintWriter pw) {
   531             generateDecl(pw);
   532             pw.printf(" { %s }", this.body);
   533         }
   535         public static ConcreteMethod std(String value) {
   536             return new ConcreteMethod(
   537                 "int", SourceModel.stdMethodName, "return " + value + ";",
   538                 AccessFlag.PUBLIC);
   539         }
   540     }
   542     // When the default method flag gets moved into the traditional
   543     // access flags location, we can remove this class completely and
   544     // use a ConcreteMethod with an AccessFlag("default") in the constructor
   545     public static class DefaultMethod extends Method {
   546         protected String body;
   548         public DefaultMethod(String ret, String name, String body,
   549                 Element ... params) {
   550             super(ret, name, params);
   551             this.body = body;
   552             this.getAccessFlags().add(AccessFlag.DEFAULT);
   553         }
   555         public void generate(PrintWriter pw) {
   556             generateDecl(pw);
   557             pw.printf(" { %s }", this.body);
   558         }
   560         public static DefaultMethod std(String value) {
   561             return new DefaultMethod(
   562                 "int", SourceModel.stdMethodName, "return " + value + ";");
   563         }
   564     }
   566     private static <T> String toJoinedString(List<T> list, String... p) {
   567         StringBuilder sb = new StringBuilder();
   568         String sep = "";
   569         String init = "";
   570         String end = "";
   571         String empty = null;
   572         switch (p.length) {
   573             case 4:
   574                 empty = p[3];
   575             /*fall-through*/
   576             case 3:
   577                 end = p[2];
   578             /*fall-through*/
   579             case 2:
   580                 init = p[1];
   581             /*fall-through*/
   582             case 1:
   583                 sep = p[0];
   584                 break;
   585         }
   586         if (empty != null && list.isEmpty()) {
   587             return empty;
   588         } else {
   589             sb.append(init);
   590             for (T x : list) {
   591                 if (sb.length() != init.length()) {
   592                     sb.append(sep);
   593                 }
   594                 sb.append(x.toString());
   595             }
   596             sb.append(end);
   597             return sb.toString();
   598         }
   599     }
   600 }

mercurial