Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openjdk/test/langtools/tools/lib/builder/   (Sun/Oracle ©)  Datei vom 13.11.2022 mit Größe 20 kB image not shown  

Quelle  ClassBuilder.java   Sprache: JAVA

 
/*
 * Copyright (c) 2018, 2022, 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.
 *
 * 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 builder;

import toolbox.ToolBox;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Builder for type declarations.
 * Note: this implementation does not support everything and is not
 * exhaustive.
 */

public class ClassBuilder extends AbstractBuilder {

    private final ToolBox tb;
    private final String fqn;
    private final String clsname;
    private final String typeParameter;

    private String pkg;
    private final List<String> imports;

    private String extendsType;
    private final List<String> implementsTypes;
    private final List<MemberBuilder> members;
    private final List<ClassBuilder> inners;
    private final List<ClassBuilder> nested;


    final static Pattern CLASS_RE = Pattern.compile("(.*)(<.*>)");

    /**
     * Creates a class builder.
     * @param tb the toolbox reference
     * @param name the name of the type
     */

    public ClassBuilder(ToolBox tb, String name) {
        super(new Modifiers(), name);
        this.tb = tb;

        Matcher m = CLASS_RE.matcher(name);
        if (m.matches()) {
            fqn = m.group(1);
            typeParameter = m.group(2);
        } else {
            fqn = name;
            typeParameter = null;
        }
        if (fqn.contains(".")) {
            this.pkg = name.substring(0, fqn.lastIndexOf('.'));
            clsname = fqn.substring(fqn.lastIndexOf('.') + 1);
        } else {
            clsname = fqn;
        }
        imports = new ArrayList<>();
        implementsTypes = new ArrayList<>();
        members = new ArrayList<>();
        nested = new ArrayList<>();
        inners = new ArrayList<>();
    }

    /**
     * Adds an import(s).
     * @param i the import type.
     * @return this builder.
     */

    public ClassBuilder addImports(String i) {
        imports.add(i);
        return this;
    }

    /**
     * Sets the modifiers for this builder.
     * @param modifiers the modifiers
     * @return this builder
     */

    public ClassBuilder setModifiers(String... modifiers) {
        this.modifiers.setModifiers(modifiers);
        return this;
    }

    /**
     * Sets the enclosing type's name.
     *
     * @param className the enclosing type's name
     */

    @Override
    void setClassName(String className) {
        cname = className;
    }

    /**
     * Sets a comment for the element.
     *
     * @param comments for the element
     * @return this builder.
     */

    @Override
    public ClassBuilder setComments(String... comments) {
        super.setComments(comments);
        return this;
    }

    /**
     * Sets a comment for the element. Typically used to set
     * the user's preferences whether an automatic comment is
     * required or no API comment.
     *
     * @param kind of comment, automatic or no comment.
     * @return this builder.
     */

    @Override
    public ClassBuilder setComments(Comment.Kind kind) {
        super.setComments(kind);
        return this;
    }

    /**
     * Set the super-type of the type.
     * @param name of the super type.
     * @return this builder.
     */

    public ClassBuilder setExtends(String name) {
        extendsType = name;
        return this;
    }

    /**
     * Adds an implements declaration(s).
     * @param names the interfaces
     * @return this builder.
     */

    public ClassBuilder addImplements(String... names) {
        implementsTypes.addAll(List.of(names));
        return this;
    }

    /**
     * Adds a member(s) to the class declaration.
     * @param mbs the member builder(s) representing member(s).
     * @return this builder
     */

    public ClassBuilder addMembers(MemberBuilder... mbs) {
        for (MemberBuilder mb : mbs) {
            members.add(mb);
            mb.setClassName(fqn);
        }
        return this;
    }

    /**
     * Adds nested-classes, to an outer class to an outer builder.
     * @param cbs class builder(s) of the nested classes.
     * @return this builder.
     */

    public ClassBuilder addNestedClasses(ClassBuilder... cbs) {
        Stream.of(cbs).forEach(cb -> {
            nested.add(cb);
            cb.setClassName(fqn);
        });
        return this;
    }

    /**
     * Adds inner-classes, to an outer class builder.
     * @param cbs class builder(s) of the inner classes.
     * @return this builder.
     */

    public ClassBuilder addInnerClasses(ClassBuilder... cbs) {
        Stream.of(cbs).forEach(cb -> {
            inners.add(cb);
            cb.setClassName(fqn);
        });
        return this;
    }

    @Override
    public String toString() {
        OutputWriter ow = new OutputWriter();
        if (pkg != null)
            ow.println("package " + pkg + ";");
        imports.forEach(i -> ow.println("import " + i + ";"));
        switch (comments.kind) {
            case AUTO:
                ow.println("/** Class " + fqn + " */");
                break;
            case USER:
                ow.println("/** ");
                comments.comments.forEach(c -> ow.println(" * " + c));
                ow.println(" */");
                break;
            case NO_API_COMMENT:
                ow.println("// NO_API_COMMENT");
                break;
        }
        ow.print(modifiers.toString());
        ow.print(clsname);
        if (typeParameter != null) {
            ow.print(typeParameter + " ");
        } else {
            ow.print(" ");
        }
        if (extendsType != null && !extendsType.isEmpty()) {
            ow.print("extends " + extendsType + " ");
        }
        if (!implementsTypes.isEmpty()) {
            ow.print("implements ");

            ListIterator<String> iter = implementsTypes.listIterator();
            while (iter.hasNext()) {
                String s = iter.next() ;
                ow.print(s);
                if (iter.hasNext())
                    ow.print(", ");
            }
        }
        ow.print("{");
        if (!nested.isEmpty()) {
            ow.println("");
            nested.forEach(m -> ow.println(m.toString()));
        }

        if (!members.isEmpty()) {
            ow.println("");
            members.forEach(m -> ow.println(m.toString()));
        }

        ow.println("}");
        if (!inners.isEmpty()) {
            ow.println(" {");
            inners.forEach(m -> ow.println(m.toString()));
            ow.println("}");
        }
        return ow.toString();
    }

    /**
     * Writes out the java source for a type element. Package directories
     * will be created as needed as inferred by the type name.
     * @param srcDir the top level source directory.
     * @throws IOException if an error occurs.
     */

    public void write(Path srcDir) throws IOException {
        Files.createDirectories(srcDir);
        Path outDir = srcDir;
        if (pkg != null && !pkg.isEmpty()) {
            String pdir = pkg.replace(".""/");
            outDir = Paths.get(srcDir.toString(), pdir);
            Files.createDirectories(outDir);
        }
        Path filePath = Paths.get(outDir.toString(), clsname + ".java");
        tb.writeFile(filePath, this.toString());
    }

    /**
     * The member builder, this is the base class for all types of members.
     */

    public static abstract class MemberBuilder extends AbstractBuilder {
        public MemberBuilder(Modifiers modifiers, String name) {
            super(modifiers, name);
        }

        /**
         * Sets the enclosing type's name.
         * @param className the enclosing type's name
         */

        @Override
        void setClassName(String className) {
            cname = className;
        }

        /**
         * Sets a comment for the element.
         *
         * @param comments for any element
         * @return this builder.
         */

        @Override
        public MemberBuilder setComments(String... comments) {
            super.setComments(comments);
            return this;
        }

        /**
         * Sets a comment for the element. Typically used to set user's
         * preferences whether an automatic comment is required or no API
         * comment.
         *
         * @param kind of comment, automatic or no comment.
         * @return this builder.
         */

        @Override
        public MemberBuilder setComments(Comment.Kind kind) {
            super.setComments(kind);
            return this;
        }

        /**
         * Sets a new modifier.
         *
         * @param modifiers
         * @return this builder.
         */

        @Override
        public MemberBuilder setModifiers(String... modifiers) {
            super.setModifiers(modifiers);
            return this;
        }
    }

    /**
     * The field builder.
     */

    public static class FieldBuilder extends MemberBuilder {
        private String fieldType;
        private String value;

        private static final Pattern FIELD_RE = Pattern.compile("(.*)(\\s*=\\s*)(.*)(;)");

        /**
         * Constructs a field with the modifiers and name of the field.
         * The builder by default is configured to auto generate the
         * comments for the field.
         * @param name of the field
         */

        public FieldBuilder(String name) {
            super(new Modifiers(), name);
            this.comments = new Comment(Comment.Kind.AUTO);
        }

        /**
         * Returns a field builder by parsing the string.
         * ex:  public static String myPlayingField;
         * @param fieldString describing the field.
         * @return a field builder.
         */

        public static FieldBuilder parse(String fieldString) {
            String prefix;
            String value = null;
            Matcher m = FIELD_RE.matcher(fieldString);
            if (m.matches()) {
                prefix = m.group(1).trim();
                value = m.group(3).trim();
            } else {
                int end = fieldString.lastIndexOf(';') > 0
                        ? fieldString.lastIndexOf(';')
                        : fieldString.length();
                prefix = fieldString.substring(0, end).trim();
            }
            List<String> list = Stream.of(prefix.split(" "))
                    .filter(s -> !s.isEmpty()).collect(Collectors.toList());
            if (list.size() < 2) {
                throw new IllegalArgumentException("incorrect field string: "
                        + fieldString);
            }
            String name = list.get(list.size() - 1);
            String fieldType = list.get(list.size() - 2);

            FieldBuilder fb = new FieldBuilder(name);
            fb.modifiers.setModifiers(list.subList(0, list.size() - 2));
            fb.setFieldType(fieldType);
            if (value != null)
                fb.setValue(value);

            return fb;
        }

        /**
         * Sets the modifiers for this builder.
         *
         * @param mods
         * @return this builder
         */

        public FieldBuilder setModifiers(String mods) {
            this.modifiers.setModifiers(mods);
            return this;
        }

        /**
         * Sets the type of the field.
         * @param fieldType the name of the type.
         * @return this field builder.
         */

        public FieldBuilder setFieldType(String fieldType) {
            this.fieldType = fieldType;
            return this;
        }

        public FieldBuilder setValue(String value) {
            this.value = value;
            return this;
        }

        @Override
        public String toString() {
            String indent = " ";
            OutputWriter ow = new OutputWriter();
            switch (comments.kind) {
                case AUTO:
                    ow.println(indent + "/** Field " +
                            super.name + " in " + super.cname + " */");
                    break;
                case INHERIT_DOC: case USER:
                    ow.println(indent + "/** " +
                            comments.toString() + " */");
                    break;
                case NO_API_COMMENT:
                    ow.println(indent + "// NO_API_COMMENT");
                    break;
            }
            ow.print(indent + super.modifiers.toString() + " ");
            ow.print(fieldType + " ");
            ow.print(super.name);
            if (value != null) {
                ow.print(" = " + value);
            }
            ow.println(";");
            return ow.toString();
        }
    }

    /**
     * The method builder.
     */

    public static class MethodBuilder extends MemberBuilder {

        private final List<Pair> params;

        private String returnType;
        private List<String> body;

        final static Pattern METHOD_RE = Pattern.compile("(.*)(\\()(.*)(\\))(.*)");

        /**
         * Constructs a method builder. The builder by default is configured
         * to auto generate the comments for this method.
         * @param name of the method.
         */

        public MethodBuilder(String name) {
            super(new Modifiers(), name);
            comments = new Comment(Comment.Kind.AUTO);
            params = new ArrayList<>();
            body = null;
        }

        /**
         * Returns a method builder by parsing a string which
         * describes a method.
         * @param methodString the method description.
         * @return a method builder.
         */

        public static MethodBuilder parse(String methodString) {
            Matcher m = METHOD_RE.matcher(methodString);
            if (!m.matches())
                throw new IllegalArgumentException("string does not match: "
                        + methodString);
            String prefix = m.group(1);
            String params = m.group(3);
            String suffix = m.group(5).trim();

            if (prefix.length() < 2) {
                throw new IllegalArgumentException("incorrect method string: "
                        + methodString);
            }

            String[] pa = prefix.split(" ");
            List<String> list = List.of(pa);
            String name = list.get(list.size() - 1);
            String returnType = list.get(list.size() - 2);

            MethodBuilder mb = new MethodBuilder(name);
            mb.modifiers.setModifiers(list.subList(0, list.size() - 2));
            mb.setReturn(returnType);

            pa = params.split(",");
            Stream.of(pa).forEach(p -> {
                p = p.trim();
                if (!p.isEmpty())
                    mb.addParameter(p);
            });
            if (!suffix.isEmpty() || suffix.length() > 1) {
                mb.setBody(suffix);
            }
            return mb;
        }

        /**
         * Sets the modifiers for this builder.
         *
         * @param modifiers
         * @return this builder
         */

        public MethodBuilder setModifiers(String modifiers) {
            this.modifiers.setModifiers(modifiers);
            return this;
        }

        @Override
        public MethodBuilder setComments(String... comments) {
            super.setComments(comments);
            return this;
        }

        @Override
        public MethodBuilder setComments(Comment.Kind kind) {
            super.setComments(kind);
            return this;
        }

        /**
         * Sets a return type for a method.
         * @param returnType the return type.
         * @return this method builder.
         */

        public MethodBuilder setReturn(String returnType) {
            this.returnType = returnType;
            return this;
        }

        /**
         * Adds a parameter(s) to the method builder.
         * @param params a pair consisting of type and parameter name.
         * @return this method builder.
         */

        public MethodBuilder addParameters(Pair... params) {
            this.params.addAll(List.of(params));
            return this;
        }

        /**
         * Adds a parameter to the method builder.
         * @param type the type of parameter.
         * @param name the parameter name.
         * @return this method builder.
         */

        public MethodBuilder addParameter(String type, String name) {
            this.params.add(new Pair(type, name));
            return this;
        }

        /**
         * Adds a parameter to the method builder, by parsing the string.
         * @param s the parameter description such as "Double voltage"
         * @return this method builder.
         */

        public MethodBuilder addParameter(String s) {
            String[] p = s.trim().split(" ");
            return addParameter(p[0], p[p.length - 1]);
        }

        /**
         * Sets the body of the method, described by the string.
         * Such as "{", "double i = v/r;", "return i;", "}"
         * @param body of the methods
         * @return
         */

        public MethodBuilder setBody(String... body) {
            if (body == null) {
                this.body = null;
            } else {
                this.body = new ArrayList<>();
                this.body.addAll(List.of(body));
            }
            return this;
        }

        @Override
        public String toString() {
            OutputWriter ow = new OutputWriter();
            String indent = " ";
            switch (comments.kind) {
                case AUTO:
                    ow.println(indent + "/** Method " + super.name + " in " + super.cname);
                    if (!params.isEmpty())
                        params.forEach(p -> ow.println(indent + " * @param " + p.second + " a param"));
                    if (returnType != null && !returnType.isEmpty() && !returnType.contains("void"))
                        ow.println(indent + " * @return returns something");
                    ow.println(indent + " */");
                    break;
                case INHERIT_DOC: case USER:
                    ow.println(indent + "/** " + comments.toString() + " */");
                    break;
                case NO_API_COMMENT:
                    ow.println(indent + "// NO_API_COMMENT");
                    break;
            }

            ow.print(indent + super.modifiers.toString() + " ");
            ow.print(returnType + " ");
            ow.print(super.name + "(");
            if (!params.isEmpty()) {
                ListIterator<Pair> iter = params.listIterator();
                while (iter.hasNext()) {
                    Pair p = iter.next();
                    ow.print(p.first + " " + p.second);
                    if (iter.hasNext())
                        ow.print(", ");
                }
            }
            ow.print(")");
            if (body == null) {
                ow.println(";");
            } else {
                body.forEach(ow::println);
            }
            return ow.toString();
        }
    }

//A sample, to test with an IDE.
//    public static void main(String... args) throws IOException {
//        ClassBuilder cb = new ClassBuilder(new ToolBox(), "foo.bar.Test<C extends A>");
//        cb.addModifiers("public", "abstract", "static")
//                .addImports("java.io").addImports("java.nio")
//                .setComments("A comment")
//                .addImplements("Serialization", "Something")
//                .setExtends("java.lang.Object")
//                .addMembers(
//                        FieldBuilder.parse("public int xxx;"),
//                        FieldBuilder.parse("public int yyy = 10;"),
//                        MethodBuilder.parse("public static void main(A a, B b, C c);")
//                            .setComments("CC"),
//                        MethodBuilder.parse("void foo(){//do something}")
//
//                );
//        ClassBuilder ic = new ClassBuilder(new ToolBox(), "IC");
//        cb.addModifiers( "interface");
//        cb.addNestedClasses(ic);
//        System.out.println(cb.toString());
//        cb.write(Paths.get("src-out"));
//    }
}

Messung V0.5
C=92 H=91 G=91

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.