<commit_before>/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package scalac.transformer;

import scalac.Global;
import scalac.util.Name;
import scalac.util.Names;

import scalac.ast.Tree;
import Tree.*;
import scalac.ast.Transformer;

import scalac.symtab.Type;
import scalac.symtab.Symbol;
import scalac.symtab.TermSymbol;
import scalac.symtab.Scope;
import scalac.symtab.Kinds;
import scalac.symtab.Modifiers;

import java.util.HashMap;
import java.util.HashSet;
import java.util.ArrayList;

import scalac.util.Debug;

/**
 * 1. For each class add a single method (DefDef) designated as
 * constructor whose parameters are the class parameters. The
 * constructor contains:
 *   - call to the constructor of the supertype with the appropriate arguments
 *   - initialize the fields corresponding to the class ValDefs
 *   - the bodies of the class level expressions;
 *     they are also removed from the ClassDef body
 *
 * 2. The right hand sides of the ValDefs are left empty
 *
 * 3. Substitute the appropriate constructor symbol into the
 * 'new' expressions
 *
 * @author <NAME>
 * @version 1.2
*/

public class AddConstructors extends Transformer {
    public final static Name CTOR_N = Names.CONSTRUCTOR;

    // True iff we generate code for INT backend.
    protected final boolean forINT;
    // True iff we generate code for JVM backend.
    protected final boolean forJVM;
    // True iff we generate code for MSIL backend.
    protected final boolean forMSIL;

    final HashMap constructors;

    public AddConstructors(Global global, HashMap constructors) {
	super(global);
        this.constructors = constructors;
        this.forINT = global.target == global.TARGET_INT;
        this.forJVM = global.target == global.TARGET_JVM;
        this.forMSIL = global.target == global.TARGET_MSIL;
    }

    /** return new constructor symbol if it isn't already defined
     */
    Symbol getConstructor(Symbol classConstr) {
	return getConstructor(classConstr,
			      (((Type.MethodType)classConstr.info()).vparams),
			      classConstr.primaryConstructorClass());
    }

    Symbol getConstructor(Symbol classConstr, Symbol[] paramSyms, Symbol owner) {
  	assert classConstr.isConstructor() :
  	    "Class constructor expected: " + Debug.show(classConstr);

	Symbol constr = (Symbol) constructors.get(classConstr);
	if (constr == null) {
	    assert !owner.isInterface() : Debug.show(owner) + " is interface";
            int flags = forJVM
                ? classConstr.flags & (Modifiers.PRIVATE | Modifiers.PROTECTED)
                : classConstr.flags;
	    constr =
                new TermSymbol(classConstr.pos, CTOR_N, owner, flags);

	    Type constrType = Type.MethodType
		(paramSyms, forJVM ?
		 global.definitions.UNIT_TYPE : owner.type()).erasure();

	    constr.setInfo(constrType.erasure());
	    constructors.put(classConstr, constr);
	    constructors.put(constr, constr);
	}

	return constr;
    }

    /** process the tree
     */
    public Tree transform(Tree tree) {
	Symbol treeSym = tree.symbol();
	switch (tree) {
	case ClassDef(_, _, _, ValDef[][] vparams, _, //:
		      Template(Tree[] baseClasses, Tree[] body)):

	    assert treeSym.name.isTypeName();

	    if (treeSym.isInterface())
		return super.transform(tree);

	    Symbol[] paramSyms = new Symbol[vparams[0].length];
	    for (int i = 0; i < paramSyms.length; i++)
		paramSyms[i] = vparams[0][i].symbol();

	    ArrayList constrBody = new ArrayList();
	    ArrayList classBody = new ArrayList();
	    Symbol constrSym =
		getConstructor(treeSym.constructor(), paramSyms, treeSym);
	    Scope classScope = new Scope();
	    classScope.enter(constrSym);

	    assert constrSym.owner() == treeSym :
		"Wrong owner of the constructor: \n\tfound: " +
		Debug.show(constrSym.owner()) + "\n\texpected: " +
		Debug.show(treeSym);

	    // inline the call to the super constructor
            Type superType = treeSym.parents()[0];
            if ( !forINT || !superType.symbol().isJava()) {
		switch (baseClasses[0]) {
		case Apply(Tree fun, Tree[] args):
		    int pos = baseClasses[0].pos;
		    Tree superConstr = gen.Select
			(gen.Super(pos, superType),
			 getConstructor(fun.symbol()));
		    constrBody.add(gen.Apply(superConstr, transform(args)));
		    break;
		default:
		    new scalac.ast.printer.TextTreePrinter().print(baseClasses[0]).println().end();
		    assert false;
		}
	    }

	    // inline initialization of module values
            if (forINT && treeSym.isModuleClass()) {
                constrBody.add(
                    gen.Assign(
                        gen.mkRef(tree.pos, treeSym.module()),
                        gen.This(tree.pos, treeSym)));
            }<commit_msg>- Fixed early initialization of module variable...<commit_after>/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package scalac.transformer;

import scalac.Global;
import scalac.util.Name;
import scalac.util.Names;

import scalac.ast.Tree;
import Tree.*;
import scalac.ast.Transformer;

import scalac.symtab.Type;
import scalac.symtab.Symbol;
import scalac.symtab.TermSymbol;
import scalac.symtab.Scope;
import scalac.symtab.Kinds;
import scalac.symtab.Modifiers;

import java.util.HashMap;
import java.util.HashSet;
import java.util.ArrayList;

import scalac.util.Debug;

/**
 * 1. For each class add a single method (DefDef) designated as
 * constructor whose parameters are the class parameters. The
 * constructor contains:
 *   - call to the constructor of the supertype with the appropriate arguments
 *   - initialize the fields corresponding to the class ValDefs
 *   - the bodies of the class level expressions;
 *     they are also removed from the ClassDef body
 *
 * 2. The right hand sides of the ValDefs are left empty
 *
 * 3. Substitute the appropriate constructor symbol into the
 * 'new' expressions
 *
 * @author <NAME>
 * @version 1.2
*/

public class AddConstructors extends Transformer {
    public final static Name CTOR_N = Names.CONSTRUCTOR;

    // True iff we generate code for INT backend.
    protected final boolean forINT;
    // True iff we generate code for JVM backend.
    protected final boolean forJVM;
    // True iff we generate code for MSIL backend.
    protected final boolean forMSIL;

    final HashMap constructors;

    public AddConstructors(Global global, HashMap constructors) {
	super(global);
        this.constructors = constructors;
        this.forINT = global.target == global.TARGET_INT;
        this.forJVM = global.target == global.TARGET_JVM;
        this.forMSIL = global.target == global.TARGET_MSIL;
    }

    /** return new constructor symbol if it isn't already defined
     */
    Symbol getConstructor(Symbol classConstr) {
	return getConstructor(classConstr,
			      (((Type.MethodType)classConstr.info()).vparams),
			      classConstr.primaryConstructorClass());
    }

    Symbol getConstructor(Symbol classConstr, Symbol[] paramSyms, Symbol owner) {
  	assert classConstr.isConstructor() :
  	    "Class constructor expected: " + Debug.show(classConstr);

	Symbol constr = (Symbol) constructors.get(classConstr);
	if (constr == null) {
	    assert !owner.isInterface() : Debug.show(owner) + " is interface";
            int flags = forJVM
                ? classConstr.flags & (Modifiers.PRIVATE | Modifiers.PROTECTED)
                : classConstr.flags;
	    constr =
                new TermSymbol(classConstr.pos, CTOR_N, owner, flags);

	    Type constrType = Type.MethodType
		(paramSyms, forJVM ?
		 global.definitions.UNIT_TYPE : owner.type()).erasure();

	    constr.setInfo(constrType.erasure());
	    constructors.put(classConstr, constr);
	    constructors.put(constr, constr);
	}

	return constr;
    }

    /** process the tree
     */
    public Tree transform(Tree tree) {
	Symbol treeSym = tree.symbol();
	switch (tree) {
	case ClassDef(_, _, _, ValDef[][] vparams, _, //:
		      Template(Tree[] baseClasses, Tree[] body)):

	    assert treeSym.name.isTypeName();

	    if (treeSym.isInterface())
		return super.transform(tree);

	    Symbol[] paramSyms = new Symbol[vparams[0].length];
	    for (int i = 0; i < paramSyms.length; i++)
		paramSyms[i] = vparams[0][i].symbol();

	    ArrayList constrBody = new ArrayList();
	    ArrayList classBody = new ArrayList();
	    Symbol constrSym =
		getConstructor(treeSym.constructor(), paramSyms, treeSym);
	    Scope classScope = new Scope();
	    classScope.enter(constrSym);

	    assert constrSym.owner() == treeSym :
		"Wrong owner of the constructor: \n\tfound: " +
		Debug.show(constrSym.owner()) + "\n\texpected: " +
		Debug.show(treeSym);

	    // inline the call to the super constructor
            Type superType = treeSym.parents()[0];
            if ( !forINT || !superType.symbol().isJava()) {
		switch (baseClasses[0]) {
		case Apply(Tree fun, Tree[] args):
		    int pos = baseClasses[0].pos;
		    Tree superConstr = gen.Select
			(gen.Super(pos, superType),
			 getConstructor(fun.symbol()));
		    constrBody.add(gen.Apply(superConstr, transform(args)));
		    break;
		default:
		    new scalac.ast.printer.TextTreePrinter().print(baseClasses[0]).println().end();
		    assert false;
		}
	    }

	    // inline initialization of module values
            if (forINT && treeSym.isModuleClass()) {
                Symbol module = treeSym.module();
                if (module.isGlobalModule()) {
                    constrBody.add(
                        gen.Assign(
                            gen.mkRef(tree.pos, module),
                            gen.This(tree.pos, treeSym)));
                } else {
                    Symbol owner = module.owner();
                    Name module_eqname = module.name.append(Names._EQ);
                    Symbol module_eq = owner.lookup(module_eqname);
                    assert module != Symbol.NONE :Debug.show(treeSym.module());
                    if (owner.isModuleClass() && owner.module().isStable()) {
                        constrBody.add(
                            gen.Apply(
                                gen.mkRef(tree.pos, module_eq),
                                new Tree[] {gen.This(tree.pos, treeSym)}));
                    } else {
                        // !!! module_eq must be accessed via some outer field
                    }
                }
            }
{'fraction_non_alphanumeric': 0.11364257723503145, 'fraction_numerical': 0.00291624897475622, 'mean_word_length': 2.323440339188371, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2882796', 'n_tokens_mistral': 3279, 'n_tokens_neox': 3083, 'n_words': 799}