<commit_before>package com.redhat.ceylon.compiler.js;

import java.util.HashMap;
import java.util.Map;

import com.redhat.ceylon.compiler.typechecker.model.ClassOrInterface;
import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Method;
import com.redhat.ceylon.compiler.typechecker.model.Package;
import com.redhat.ceylon.compiler.typechecker.model.TypeDeclaration;

/**
 * Manages the identifier names in the JavaScript code generated for a Ceylon
 * compilation unit.
 * 
 * @author <NAME>
 */
public class JsIdentifierNames {

    private boolean prototypeStyle = false;
    
    private static long uniqueID = 0;
    private static long nextUID() {
        if (++uniqueID <= 0) {
            uniqueID = 1;
        }
        return uniqueID;
    }
    
    public JsIdentifierNames(boolean prototypeStyle) {
        this.prototypeStyle = prototypeStyle;
    }
    
    /**
     * Determine the identifier name to be used in the generated JavaScript code
     * to represent the given declaration.
     */
    public String name(Declaration decl) {
        return getName(decl, false);
    }
    
    /**
     * Determine the function name to be used in the generated JavaScript code
     * for the getter of the given declaration.
     */
    public String getter(Declaration decl) {
        String name = getName(decl, true);
        return String.format("get%c%s", Character.toUpperCase(name.charAt(0)),
                name.substring(1));
    }
    
    /**
     * Determine the function name to be used in the generated JavaScript code
     * for the setter of the given declaration.
     */
    public String setter(Declaration decl) {
        String name = getName(decl, true);
        return String.format("set%c%s", Character.toUpperCase(name.charAt(0)),
                name.substring(1));
    }
    
    /**
     * Determine the identifier to be used in the generated JavaScript code as
     * an alias for the given package.
     */
    public String packageAlias(Package pkg) {
        StringBuilder sb = new StringBuilder("$$$");
        for (String s: pkg.getName()) {
            sb.append(s.substring(0,1));
        }
        sb.append(getUID(pkg));
        return sb.toString();
    }
    
    /**
     * Creates a new unique identifier.
     */
    public String createTempVariable(String baseName) {
        return String.format("%s$%d", baseName, nextUID());
    }
    
    /**
     * Creates a new unique identifier.
     */
    public String createTempVariable() {
        return createTempVariable("tmpvar");
    }
    
    /**
     * Determine identifier to be used for the self variable of the given type.
     */
    public String self(TypeDeclaration d) {
        String name = d.getName();
        if (!(d.isShared() || d.isToplevel())) {
            name = String.format("%s$%d", name, getUID(d));
        }
        // TODO: shared or toplevel types probably also need a suffix in some cases
        return String.format("$$%c%s", Character.toLowerCase(name.charAt(0)),
                    name.substring(1));
    }
    
    /**
     * Returns a disambiguation suffix for the given type. It is guaranteed that
     * the suffixes generated for two different types are different.
     */
    public String memberSuffix(TypeDeclaration typeDecl) {
        // TODO: we need to take the qualified path into account!
        return String.format("$%s$", typeDecl.getName());
    }
    
    public void forceName(Declaration decl, String name) {
        uniqueVarNames.put(decl, name);
    }
    
    private Map<Package, Long> packageUIDs = new HashMap<Package, Long>();
    private Map<Declaration, Long> uniqueVarIDs = new HashMap<Declaration, Long>();
    private Map<Declaration, String> uniqueVarNames =
            new HashMap<Declaration, String>();
    
    private String getName(Declaration d, boolean forGetterSetter) {
        String name = d.getName();
        if (!((d.isShared() || d.isToplevel())
                && (forGetterSetter || (d instanceof Method)
                        || (d instanceof ClassOrInterface)))) {
            name = uniqueVarNames.get(d);
            if (name == null) {
                String format = (prototypeStyle && d.isMember()) ? "%s$%d$" : "%s$%d";
                name = String.format(format, d.getName(), getUID(d));
            }
        }
        // TODO: shared or toplevel functions/types probably also need a suffix in some cases
        return name;
    }
    
    private long getUID(Declaration decl) {
        Long id = uniqueVarIDs.get(decl);
        if (id == null) {
            id = nextUID();
            uniqueVarIDs.put(decl, id);
        }
        return id;
    }
    
    private long getUID(Package pkg) {
        Long id = packageUIDs.get(pkg);
        if (id == null) {
            id = nextUID();
            packageUIDs.put(pkg, id);
        }
        return id;
    }
    
}
<commit_msg>improve generated names for inner types (for #44)<commit_after>package com.redhat.ceylon.compiler.js;

import java.util.HashMap;
import java.util.Map;

import com.redhat.ceylon.compiler.typechecker.model.ClassOrInterface;
import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Method;
import com.redhat.ceylon.compiler.typechecker.model.Package;
import com.redhat.ceylon.compiler.typechecker.model.Scope;
import com.redhat.ceylon.compiler.typechecker.model.TypeDeclaration;

/**
 * Manages the identifier names in the JavaScript code generated for a Ceylon
 * compilation unit.
 * 
 * @author <NAME>
 */
public class JsIdentifierNames {

    private boolean prototypeStyle = false;
    
    private static long uniqueID = 0;
    private static long nextUID() {
        if (++uniqueID <= 0) {
            uniqueID = 1;
        }
        return uniqueID;
    }
    
    public JsIdentifierNames(boolean prototypeStyle) {
        this.prototypeStyle = prototypeStyle;
    }
    
    /**
     * Determine the identifier name to be used in the generated JavaScript code
     * to represent the given declaration.
     */
    public String name(Declaration decl) {
        return getName(decl, false);
    }
    
    /**
     * Determine the function name to be used in the generated JavaScript code
     * for the getter of the given declaration.
     */
    public String getter(Declaration decl) {
        String name = getName(decl, true);
        return String.format("get%c%s", Character.toUpperCase(name.charAt(0)),
                name.substring(1));
    }
    
    /**
     * Determine the function name to be used in the generated JavaScript code
     * for the setter of the given declaration.
     */
    public String setter(Declaration decl) {
        String name = getName(decl, true);
        return String.format("set%c%s", Character.toUpperCase(name.charAt(0)),
                name.substring(1));
    }
    
    /**
     * Determine the identifier to be used in the generated JavaScript code as
     * an alias for the given package.
     */
    public String packageAlias(Package pkg) {
        StringBuilder sb = new StringBuilder("$$$");
        for (String s: pkg.getName()) {
            sb.append(s.substring(0,1));
        }
        sb.append(getUID(pkg));
        return sb.toString();
    }
    
    /**
     * Creates a new unique identifier.
     */
    public String createTempVariable(String baseName) {
        return String.format("%s$%d", baseName, nextUID());
    }
    
    /**
     * Creates a new unique identifier.
     */
    public String createTempVariable() {
        return createTempVariable("tmpvar");
    }
    
    /**
     * Determine identifier to be used for the self variable of the given type.
     */
    public String self(TypeDeclaration decl) {
        String name = decl.getName();
        if (!(decl.isShared() || decl.isToplevel())) {
            name = String.format("%s$%d", name, getUID(decl));
        } else {
            name += nestingSuffix(decl);
        }
        return String.format("$$%c%s", Character.toLowerCase(name.charAt(0)),
                    name.substring(1));
    }
    
    /**
     * Returns a disambiguation suffix for the given type. It is guaranteed that
     * the suffixes generated for two different types are different.
     */
    public String memberSuffix(TypeDeclaration typeDecl) {
        // TODO: we need to take the qualified path into account!
        return String.format("$%s$", typeDecl.getName());
    }
    
    private String nestingSuffix(Declaration decl) {
        String suffix = "";
        if (decl instanceof TypeDeclaration) {
            StringBuilder sb = new StringBuilder();
            Scope scope = decl.getContainer();
            while (scope instanceof TypeDeclaration) {
                sb.append('$');
                sb.append(((TypeDeclaration) scope).getName());
                scope = scope.getContainer();
            }
            suffix = sb.toString();
        }
        return suffix;
    }
    
    public void forceName(Declaration decl, String name) {
        uniqueVarNames.put(decl, name);
    }
    
    private Map<Package, Long> packageUIDs = new HashMap<Package, Long>();
    private Map<Declaration, Long> uniqueVarIDs = new HashMap<Declaration, Long>();
    private Map<Declaration, String> uniqueVarNames =
            new HashMap<Declaration, String>();
    
    private String getName(Declaration decl, boolean forGetterSetter) {
        String name = decl.getName();
        if (!((decl.isShared() || decl.isToplevel())
                && (forGetterSetter || (decl instanceof Method)
                        || (decl instanceof ClassOrInterface)))) {
            name = uniqueVarNames.get(decl);
            if (name == null) {
                String format = (prototypeStyle && decl.isMember()) ? "%s$%d$" : "%s$%d";
                name = String.format(format, decl.getName(), getUID(decl));
            }
        } else {
            name += nestingSuffix(decl);
        }
        return name;
    }
    
    private long getUID(Declaration decl) {
        Long id = uniqueVarIDs.get(decl);
        if (id == null) {
            id = nextUID();
            uniqueVarIDs.put(decl, id);
        }
        return id;
    }
    
    private long getUID(Package pkg) {
        Long id = packageUIDs.get(pkg);
        if (id == null) {
            id = nextUID();
            packageUIDs.put(pkg, id);
        }
        return id;
    }
    
}

{'fraction_non_alphanumeric': 0.11014851485148515, 'fraction_numerical': 0.002284843869002285, 'mean_word_length': 2.2027439024390243, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2892645', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2830, 'n_words': 809}