/**
 * Code for generating .json descriptions of the module when passing the `-X` flag to dmd.
 *
 * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
 * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
 * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/json.d, _json.d)
 * Documentation:  https://dlang.org/phobos/dmd_json.html
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/json.d
 */

module dmd.json;

import core.stdc.stdio;
import core.stdc.string;
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
import dmd.cond;
import dmd.dclass;
import dmd.declaration;
import dmd.denum;
import dmd.dimport;
import dmd.dmodule;
import dmd.dsymbol;
import dmd.dtemplate;
import dmd.errors;
import dmd.expression;
import dmd.func;
import dmd.globals;
import dmd.hdrgen;
import dmd.id;
import dmd.identifier;
import dmd.location;
import dmd.mtype;
import dmd.common.outbuffer;
import dmd.root.rootobject;
import dmd.root.string;
import dmd.target;
import dmd.visitor;

version(Windows) {
    extern (C) char* getcwd(char* buffer, size_t maxlen);
} else {
    import core.sys.posix.unistd : getcwd;
}

private extern (C++) final class ToJsonVisitor : Visitor
{
    alias visit = Visitor.visit;
public:
    OutBuffer* buf;
    int indentLevel;
    const(char)[] filename;

    extern (D) this(OutBuffer* buf) scope
    {
        this.buf = buf;
    }


    void indent()
    {
        if (buf.length >= 1 && (*buf)[buf.length - 1] == '\n')
            for (int i = 0; i < indentLevel; i++)
                buf.writeByte(' ');
    }

    void removeComma()
    {
        if (buf.length >= 2 && (*buf)[buf.length - 2] == ',' && ((*buf)[buf.length - 1] == '\n' || (*buf)[buf.length - 1] == ' '))
            buf.setsize(buf.length - 2);
    }

    void comma()
    {
        if (indentLevel > 0)
            buf.writestring(",\n");
    }

    void stringStart()
    {
        buf.writeByte('\"');
    }

    void stringEnd()
    {
        buf.writeByte('\"');
    }

    extern(D) void stringPart(const char[] s)
    {
        foreach (char c; s)
        {
            switch (c)
            {
            case '\n':
                buf.writestring("\\n");
                break;
            case '\r':
                buf.writestring("\\r");
                break;
            case '\t':
                buf.writestring("\\t");
                break;
            case '\"':
                buf.writestring("\\\"");
                break;
            case '\\':
                buf.writestring("\\\\");
                break;
            case '\b':
                buf.writestring("\\b");
                break;
            case '\f':
                buf.writestring("\\f");
                break;
            default:
                if (c < 0x20)
                    buf.printf("\\u%04x", c);
                else
                {
                    // Note that UTF-8 chars pass through here just fine
                    buf.writeByte(c);
                }
                break;
            }
        }
    }

    // Json value functions
    /*********************************
     * Encode string into buf, and wrap it in double quotes.
     */
    extern(D) void value(const char[] s)
    {
        stringStart();
        stringPart(s);
        stringEnd();
    }

    void value(int value)
    {
        if (value < 0)
        {
            buf.writeByte('-');
            value = -value;
        }
        buf.print(value);
    }

    void valueBool(bool value)
    {
        buf.writestring(value ? "true" : "false");
    }

    /*********************************
     * Item is an intented value and a comma, for use in arrays
     */
    extern(D) void item(const char[] s)
    {
        indent();
        value(s);
        comma();
    }

    void item(int i)
    {
        indent();
        value(i);
        comma();
    }

    void itemBool(const bool b)
    {
        indent();
        valueBool(b);
        comma();
    }

    // Json array functions
    void arrayStart()
    {
        indent();
        buf.writestring("[\n");
        indentLevel++;
    }

    void arrayEnd()
    {
        indentLevel--;
        removeComma();
        if (buf.length >= 2 && (*buf)[buf.length - 2] == '[' && (*buf)[buf.length - 1] == '\n')
            buf.setsize(buf.length - 1);
        else if (!(buf.length >= 1 && (*buf)[buf.length - 1] == '['))
        {
            buf.writestring("\n");
            indent();
        }
        buf.writestring("]");
        comma();
    }

    // Json object functions
    void objectStart()
    {
        indent();
        buf.writestring("{\n");
        indentLevel++;
    }

    void objectEnd()
    {
        indentLevel--;
        removeComma();
        if (buf.length >= 2 && (*buf)[buf.length - 2] == '{' && (*buf)[buf.length - 1] == '\n')
            buf.setsize(buf.length - 1);
        else
        {
            buf.writestring("\n");
            indent();
        }
        buf.writestring("}");
        comma();
    }

    // Json object property functions
    extern(D) void propertyStart(const char[] name)
    {
        indent();
        value(name);
        buf.writestring(" : ");
    }

    /**
    Write the given string object property only if `s` is not null.

    Params:
     name = the name of the object property
     s = the string value of the object property
    */
    extern(D) void property(const char[] name, const char[] s)
    {
        if (s is null)
            return;
        propertyStart(name);
        value(s);
        comma();
    }

    /**
    Write the given string object property.

    Params:
     name = the name of the object property
     s = the string value of the object property
    */
    extern(D) void requiredProperty(const char[] name, const char[] s)
    {
        propertyStart(name);
        if (s is null)
            buf.writestring("null");
        else
            value(s);
        comma();
    }

    extern(D) void property(const char[] name, int i)
    {
        propertyStart(name);
        value(i);
        comma();
    }

    extern(D) void propertyBool(const char[] name, const bool b)
    {
        propertyStart(name);
        valueBool(b);
        comma();
    }

    extern(D) void property(const char[] name, TRUST trust)
    {
        final switch (trust)
        {
        case TRUST.default_:
            // Should not be printed
            //property(name, "default");
            break;
        case TRUST.system:  return property(name, "system");
        case TRUST.trusted: return property(name, "trusted");
        case TRUST.safe:    return property(name, "safe");
        }
    }

    extern(D) void property(const char[] name, PURE purity)
    {
        final switch (purity)
        {
        case PURE.impure:
            // Should not be printed
            //property(name, "impure");
            break;
        case PURE.weak:     return property(name, "weak");
        case PURE.const_:   return property(name, "strong");
        case PURE.fwdref:   return property(name, "fwdref");
        }
    }

    extern(D) void property(const char[] name, const LINK linkage)
    {
        final switch (linkage)
        {
        case LINK.default_:
            // Should not be printed
            //property(name, "default");
            break;
        case LINK.d:
            // Should not be printed
            //property(name, "d");
            break;
        case LINK.system:   return property(name, "system");
        case LINK.c:        return property(name, "c");
        case LINK.cpp:      return property(name, "cpp");
        case LINK.windows:  return property(name, "windows");
        case LINK.objc:     return property(name, "objc");
        }
    }

    extern(D) void propertyStorageClass(const char[] name, StorageClass stc)
    {
        stc &= STC.visibleStorageClasses;
        if (stc)
        {
            propertyStart(name);
            arrayStart();
            while (stc)
            {
                auto p = stcToString(stc);
                assert(p.length);
                item(p);
            }
            arrayEnd();
        }
    }

    extern(D) void property(const char[] linename, const char[] charname, const ref Loc loc)
    {
        if (loc.isValid())
        {
            if (auto filename = loc.filename.toDString)
            {
                if (filename != this.filename)
                {
                    this.filename = filename;
                    property("file", filename);
                }
            }
            if (loc.linnum)
            {
                property(linename, loc.linnum);
                if (loc.charnum)
                    property(charname, loc.charnum);
            }
        }
    }

    extern(D) void property(const char[] name, Type type)
    {
        if (type)
        {
            property(name, type.toString());
        }
    }

    extern(D) void property(const char[] name, const char[] deconame, Type type)
    {
        if (type)
        {
            if (type.deco)
                property(deconame, type.deco.toDString);
            else
                property(name, type.toString());
        }
    }

    extern(D) void property(const char[] name, Parameters* parameters)
    {
        if (parameters is null || parameters.length == 0)
            return;
        propertyStart(name);
        arrayStart();
        if (parameters)
        {
            for (size_t i = 0; i < parameters.length; i++)
            {
                Parameter p = (*parameters)[i];
                objectStart();
                if (p.ident)
                    property("name", p.ident.toString());
                property("type", "deco", p.type);
                propertyStorageClass("storageClass", p.storageClass);
                if (p.defaultArg)
                    property("default", p.defaultArg.toString());
                objectEnd();
            }
        }
        arrayEnd();
    }

    /* ========================================================================== */
    void jsonProperties(Dsymbol s)
    {
        if (s.isModule())
            return;
        if (!s.isTemplateDeclaration()) // TemplateDeclaration::kind() acts weird sometimes
        {
            property("name", s.toString());
            if (s.isStaticCtorDeclaration())
            {
                property("kind", s.isSharedStaticCtorDeclaration()
                         ? "shared static constructor" : "static constructor");
            }
            else if (s.isStaticDtorDeclaration())
            {
                property("kind", s.isSharedStaticDtorDeclaration()
                         ? "shared static destructor" : "static destructor");
            }
            else
                property("kind", s.kind.toDString);
        }
        // TODO: How about package(names)?
        property("protection", visibilityToString(s.visible().kind));
        if (EnumMember em = s.isEnumMember())
        {
            if (em.origValue)
                property("value", em.origValue.toString());
        }
        property("comment", s.comment.toDString);
        property("line", "char", s.loc);
    }

    void jsonProperties(Declaration d)
    {
        if (d.storage_class & STC.local)
            return;
        jsonProperties(cast(Dsymbol)d);
        propertyStorageClass("storageClass", d.storage_class);
        property("linkage", d._linkage);
        property("type", "deco", d.type);
        // Emit originalType if it differs from type
        if (d.type != d.originalType && d.originalType)
        {
            auto ostr = d.originalType.toString();
            if (d.type)
            {
                auto tstr = d.type.toString();
                if (ostr != tstr)
                {
                    //printf("tstr = %s, ostr = %s\n", tstr, ostr);
                    property("originalType", ostr);
                }
            }
            else
                property("originalType", ostr);
        }
    }

    void jsonProperties(TemplateDeclaration td)
    {
        jsonProperties(cast(Dsymbol)td);
        if (td.onemember && td.onemember.isCtorDeclaration())
            property("name", "this"); // __ctor -> this
        else
            property("name", td.ident.toString()); // Foo(T) -> Foo
    }

    /* ========================================================================== */
    override void visit(Dsymbol s)
    {
    }

    override void visit(Module s)
    {
        objectStart();
        if (s.md)
            property("name", s.md.toString());
        property("kind", s.kind.toDString);
        filename = s.srcfile.toString();
        property("file", filename);
        property("comment", s.comment.toDString);
        propertyStart("members");
        arrayStart();
        for (size_t i = 0; i < s.members.length; i++)
        {
            (*s.members)[i].accept(this);
        }
        arrayEnd();
        objectEnd();
    }

    override void visit(Import s)
    {
        if (s.id == Id.object)
            return;
        objectStart();
        propertyStart("name");
        stringStart();
        foreach (const pid; s.packages){
            stringPart(pid.toString());
            buf.writeByte('.');
        }
        stringPart(s.id.toString());
        stringEnd();
        comma();
        property("kind", s.kind.toDString);
        property("comment", s.comment.toDString);
        property("line", "char", s.loc);
        if (s.visible().kind != Visibility.Kind.public_)
            property("protection", visibilityToString(s.visible().kind));
        if (s.aliasId)
            property("alias", s.aliasId.toString());
        bool hasRenamed = false;
        bool hasSelective = false;
        for (size_t i = 0; i < s.aliases.length; i++)
        {
            // avoid empty "renamed" and "selective" sections
            if (hasRenamed && hasSelective)
                break;
            else if (s.aliases[i])
                hasRenamed = true;
            else
                hasSelective = true;
        }
        if (hasRenamed)
        {
            // import foo : alias1 = target1;
            propertyStart("renamed");
            objectStart();
            for (size_t i = 0; i < s.aliases.length; i++)
            {
                const name = s.names[i];
                const _alias = s.aliases[i];
                if (_alias)
                    property(_alias.toString(), name.toString());
            }
            objectEnd();
        }
        if (hasSelective)
        {
            // import foo : target1;
            propertyStart("selective");
            arrayStart();
            foreach (i, name; s.names)
            {
                if (!s.aliases[i])
                    item(name.toString());
            }
            arrayEnd();
        }
        objectEnd();
    }

    override void visit(AttribDeclaration d)
    {
        Dsymbols* ds = d.include(null);
        if (ds)
        {
            for (size_t i = 0; i < ds.length; i++)
            {
                Dsymbol s = (*ds)[i];
                s.accept(this);
            }
        }
    }

    override void visit(ConditionalDeclaration d)
    {
        if (d.condition.inc != Include.notComputed)
        {
            visit(cast(AttribDeclaration)d);
            return; // Don't visit the if/else bodies again below
        }
        Dsymbols* ds = d.decl ? d.decl : d.elsedecl;
        for (size_t i = 0; i < ds.length; i++)
        {
            Dsymbol s = (*ds)[i];
            s.accept(this);
        }
    }

    override void visit(TypeInfoDeclaration d)
    {
    }

    override void visit(PostBlitDeclaration d)
    {
    }

    override void visit(Declaration d)
    {
        objectStart();
        //property("unknown", "declaration");
        jsonProperties(d);
        objectEnd();
    }

    override void visit(AggregateDeclaration d)
    {
        objectStart();
        jsonProperties(d);
        ClassDeclaration cd = d.isClassDeclaration();
        if (cd)
        {
            if (cd.baseClass && cd.baseClass.ident != Id.Object)
            {
                property("base", cd.baseClass.toPrettyChars(true).toDString);
            }
            if (cd.interfaces.length)
            {
                propertyStart("interfaces");
                arrayStart();
                foreach (b; cd.interfaces)
                {
                    item(b.sym.toPrettyChars(true).toDString);
                }
                arrayEnd();
            }
        }
        if (d.members)
        {
            propertyStart("members");
            arrayStart();
            for (size_t i = 0; i < d.members.length; i++)
            {
                Dsymbol s = (*d.members)[i];
                s.accept(this);
            }
            arrayEnd();
        }
        objectEnd();
    }

    override void visit(FuncDeclaration d)
    {
        objectStart();
        jsonProperties(d);
        TypeFunction tf = cast(TypeFunction)d.type;
        if (tf && tf.ty == Tfunction)
            property("parameters", tf.parameterList.parameters);
        property("endline", "endchar", d.endloc);
        if (d.foverrides.length)
        {
            propertyStart("overrides");
            arrayStart();
            for (size_t i = 0; i < d.foverrides.length; i++)
            {
                FuncDeclaration fd = d.foverrides[i];
                item(fd.toPrettyChars().toDString);
            }
            arrayEnd();
        }
        if (d.fdrequire)
        {
            propertyStart("in");
            d.fdrequire.accept(this);
        }
        if (d.fdensure)
        {
            propertyStart("out");
            d.fdensure.accept(this);
        }
        objectEnd();
    }

    override void visit(TemplateDeclaration d)
    {
        objectStart();
        // TemplateDeclaration::kind returns the kind of its Aggregate onemember, if it is one
        property("kind", "template");
        jsonProperties(d);
        propertyStart("parameters");
        arrayStart();
        for (size_t i = 0; i < d.parameters.length; i++)
        {
            TemplateParameter s = (*d.parameters)[i];
            objectStart();
            property("name", s.ident.toString());

            if (auto type = s.isTemplateTypeParameter())
            {
                if (s.isTemplateThisParameter())
                    property("kind", "this");
                else
                    property("kind", "type");
                property("type", "deco", type.specType);
                property("default", "defaultDeco", type.defaultType);
            }

            if (auto value = s.isTemplateValueParameter())
            {
                property("kind", "value");
                property("type", "deco", value.valType);
                if (value.specValue)
                    property("specValue", value.specValue.toString());
                if (value.defaultValue)
                    property("defaultValue", value.defaultValue.toString());
            }

            if (auto _alias = s.isTemplateAliasParameter())
            {
                property("kind", "alias");
                property("type", "deco", _alias.specType);
                if (_alias.specAlias)
                    property("specAlias", _alias.specAlias.toString());
                if (_alias.defaultAlias)
                    property("defaultAlias", _alias.defaultAlias.toString());
            }

            if (auto tuple = s.isTemplateTupleParameter())
            {
                property("kind", "tuple");
            }

            objectEnd();
        }
        arrayEnd();
        Expression expression = d.constraint;
        if (expression)
        {
            property("constraint", expression.toString());
        }
        propertyStart("members");
        arrayStart();
        for (size_t i = 0; i < d.members.length; i++)
        {
            Dsymbol s = (*d.members)[i];
            s.accept(this);
        }
        arrayEnd();
        objectEnd();
    }

    override void visit(EnumDeclaration d)
    {
        if (d.isAnonymous())
        {
            if (d.members)
            {
                for (size_t i = 0; i < d.members.length; i++)
                {
                    Dsymbol s = (*d.members)[i];
                    s.accept(this);
                }
            }
            return;
        }
        objectStart();
        jsonProperties(d);
        property("base", "baseDeco", d.memtype);
        if (d.members)
        {
            propertyStart("members");
            arrayStart();
            for (size_t i = 0; i < d.members.length; i++)
            {
                Dsymbol s = (*d.members)[i];
                s.accept(this);
            }
            arrayEnd();
        }
        objectEnd();
    }

    override void visit(EnumMember s)
    {
        objectStart();
        jsonProperties(cast(Dsymbol)s);
        property("type", "deco", s.origType);
        objectEnd();
    }

    override void visit(VarDeclaration d)
    {
        if (d.storage_class & STC.local)
            return;
        objectStart();
        jsonProperties(d);
        if (d._init)
            property("init", d._init.toString());
        if (d.isField())
            property("offset", d.offset);
        if (!d.alignment.isUnknown() && !d.alignment.isDefault())
            property("align", d.alignment.get());
        objectEnd();
    }

    override void visit(TemplateMixin d)
    {
        objectStart();
        jsonProperties(d);
        objectEnd();
    }

    /**
    Generate an array of module objects that represent the syntax of each
    "root module".

    Params:
     modules = array of the "root modules"
    */
    private void generateModules(Modules* modules)
    {
        arrayStart();
        if (modules)
        {
            foreach (m; *modules)
            {
                if (global.params.verbose)
                    message("json gen %s", m.toChars());
                m.accept(this);
            }
        }
        arrayEnd();
    }

    /**
    Generate the "compilerInfo" object which contains information about the compiler
    such as the filename, version, supported features, etc.
    */
    private void generateCompilerInfo()
    {
        import dmd.target : target;
        objectStart();
        requiredProperty("vendor", global.vendor);
        requiredProperty("version", global.versionString());
        property("__VERSION__", global.versionNumber());
        requiredProperty("interface", determineCompilerInterface());
        property("size_t", size_t.sizeof);
        propertyStart("platforms");
        arrayStart();
        if (target.os == Target.OS.Windows)
        {
            item("windows");
        }
        else
        {
            item("posix");
            if (target.os == Target.OS.linux)
                item("linux");
            else if (target.os == Target.OS.OSX)
                item("osx");
            else if (target.os == Target.OS.FreeBSD)
            {
                item("freebsd");
                item("bsd");
            }
            else if (target.os == Target.OS.OpenBSD)
            {
                item("openbsd");
                item("bsd");
            }
            else if (target.os == Target.OS.Solaris)
            {
                item("solaris");
                item("bsd");
            }
        }
        arrayEnd();

        propertyStart("architectures");
        arrayStart();
        item(target.architectureName);
        arrayEnd();

        propertyStart("predefinedVersions");
        arrayStart();
        if (global.versionids)
        {
            foreach (const versionid; *global.versionids)
            {
                item(versionid.toString());
            }
        }
        arrayEnd();

        propertyStart("supportedFeatures");
        {
            objectStart();
            scope(exit) objectEnd();
            propertyBool("includeImports", true);
        }
        objectEnd();
    }

    /**
    Generate the "buildInfo" object which contains information specific to the
    current build such as CWD, importPaths, configFile, etc.
    */
    private void generateBuildInfo()
    {
        objectStart();
        requiredProperty("cwd", getcwd(null, 0).toDString);
        requiredProperty("argv0", global.params.argv0);
        requiredProperty("config", global.inifilename);
        requiredProperty("libName", global.params.libname);

        propertyStart("importPaths");
        arrayStart();
        if (global.params.imppath)
        {
            foreach (importPath; *global.params.imppath)
            {
                item(importPath.toDString);
            }
        }
        arrayEnd();

        propertyStart("objectFiles");
        arrayStart();
        foreach (objfile; global.params.objfiles)
        {
            item(objfile.toDString);
        }
        arrayEnd();

        propertyStart("libraryFiles");
        arrayStart();
        foreach (lib; global.params.libfiles)
        {
            item(lib.toDString);
        }
        arrayEnd();

        propertyStart("ddocFiles");
        arrayStart();
        foreach (ddocFile; global.params.ddoc.files)
        {
            item(ddocFile.toDString);
        }
        arrayEnd();

        requiredProperty("mapFile", global.params.mapfile);
        requiredProperty("resourceFile", global.params.resfile);
        requiredProperty("defFile", global.params.deffile);

        objectEnd();
    }

    /**
    Generate the "semantics" object which contains a 'modules' field representing
    semantic information about all the modules used in the compilation such as
    module name, isRoot, contentImportedFiles, etc.
    */
    private void generateSemantics()
    {
        objectStart();
        propertyStart("modules");
        arrayStart();
        foreach (m; Module.amodules)
        {
            objectStart();
            requiredProperty("name", m.md ? m.md.toString() : null);
            requiredProperty("file", m.srcfile.toString());
            propertyBool("isRoot", m.isRoot());
            if(m.contentImportedFiles.length > 0)
            {
                propertyStart("contentImports");
                arrayStart();
                foreach (file; m.contentImportedFiles)
                {
                    item(file.toDString);
                }
                arrayEnd();
            }
            objectEnd();
        }
        arrayEnd();
        objectEnd();
    }
}

extern (C++) void json_generate(OutBuffer* buf, Modules* modules)
{
    scope ToJsonVisitor json = new ToJsonVisitor(buf);
    // write trailing newline
    scope(exit) buf.writeByte('\n');

    if (global.params.jsonFieldFlags == 0)
    {
        // Generate the original format, which is just an array
        // of modules representing their syntax.
        json.generateModules(modules);
        json.removeComma();
    }
    else
    {
        // Generate the new format which is an object where each
        // output option is its own field.

        json.objectStart();
        if (global.params.jsonFieldFlags & JsonFieldFlags.compilerInfo)
        {
            json.propertyStart("compilerInfo");
            json.generateCompilerInfo();
        }
        if (global.params.jsonFieldFlags & JsonFieldFlags.buildInfo)
        {
            json.propertyStart("buildInfo");
            json.generateBuildInfo();
        }
        if (global.params.jsonFieldFlags & JsonFieldFlags.modules)
        {
            json.propertyStart("modules");
            json.generateModules(modules);
        }
        if (global.params.jsonFieldFlags & JsonFieldFlags.semantics)
        {
            json.propertyStart("semantics");
            json.generateSemantics();
        }
        json.objectEnd();
    }
}

/**
A string listing the name of each JSON field. Useful for errors messages.
*/
enum jsonFieldNames = () {
    string s;
    string prefix = "";
    foreach (idx, enumName; __traits(allMembers, JsonFieldFlags))
    {
        static if (idx > 0)
        {
            s ~= prefix ~ "`" ~ enumName ~ "`";
            prefix = ", ";
        }
    }
    return s;
}();

/**
Parse the given `fieldName` and return its corresponding JsonFieldFlags value.

Params:
 fieldName = the field name to parse

Returns: JsonFieldFlags.none on error, otherwise the JsonFieldFlags value
         corresponding to the given fieldName.
*/
extern (C++) JsonFieldFlags tryParseJsonField(const(char)* fieldName)
{
    auto fieldNameString = fieldName.toDString();
    foreach (idx, enumName; __traits(allMembers, JsonFieldFlags))
    {
        static if (idx > 0)
        {
            if (fieldNameString == enumName)
                return __traits(getMember, JsonFieldFlags, enumName);
        }
    }
    return JsonFieldFlags.none;
}

/**
Determines and returns the compiler interface which is one of `dmd`, `ldc`,
`gdc` or `sdc`. Returns `null` if no interface can be determined.
*/
private extern(D) string determineCompilerInterface()
{
    if (global.vendor == "Digital Mars D")
        return "dmd";
    if (global.vendor == "LDC")
        return "ldc";
    if (global.vendor == "GNU D")
        return "gdc";
    if (global.vendor == "SDC")
        return "sdc";
    return null;
}
