diff options
author | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2005-12-18 18:33:03 +0000 |
---|---|---|
committer | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2005-12-18 18:33:03 +0000 |
commit | d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a (patch) | |
tree | dfc6f7f497e58ea3321e6f687b11313d2afa86b5 /sources/scalac | |
parent | 0e82079908655682e5140ad521cef0572cb6d2a4 (diff) | |
download | scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.tar.gz scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.tar.bz2 scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.zip |
Removed old Scalac code in sources and various ...
Removed old Scalac code in sources and various other obsolete elements.
Diffstat (limited to 'sources/scalac')
121 files changed, 0 insertions, 39216 deletions
diff --git a/sources/scalac/ApplicationError.java b/sources/scalac/ApplicationError.java deleted file mode 100644 index 5c00567d50..0000000000 --- a/sources/scalac/ApplicationError.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac; - -import scalac.util.Debug; - -public class ApplicationError extends Error { - - //######################################################################## - // Private interface - - private static String combine(String message, Object object) { - String string = Debug.show(object); - return message == null ? string : message + ": " + string; - } - - //######################################################################## - // ApplicationError constructors - - public ApplicationError() { - this((String)null, (Throwable)null); - } - - public ApplicationError(String message) { - this(message, (Throwable)null); - } - - public ApplicationError(Object object) { - this(null, object, null); - } - - public ApplicationError(Throwable cause) { - this((String)null, cause); - } - - public ApplicationError(String message, Object object) { - this(message, object, null); - } - - public ApplicationError(String message, Throwable cause) { - super(message, cause); - } - - public ApplicationError(Object object, Throwable cause) { - this(null, object, cause); - } - - public ApplicationError(String message, Object object, Throwable cause) { - this(combine(message, object), cause); - } - - //######################################################################## -} diff --git a/sources/scalac/CompilationLoop.java b/sources/scalac/CompilationLoop.java deleted file mode 100644 index 94700d355d..0000000000 --- a/sources/scalac/CompilationLoop.java +++ /dev/null @@ -1,143 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import java.util.ArrayList; - -import scalac.util.Debug; - -/** This class implements the scalac compilation loop. */ -public class CompilationLoop { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - /** The list of active phases */ - private final Phase[] phases; - /** The units currently associated to each active phase. */ - private final ArrayList/*<CompilationUnit>*/[] unitss; - /** The indexes of the first units that are not yet processed. */ - private final int[] indexes; - - //######################################################################## - // Private Constructors - - /** Initializes this instance. */ - public CompilationLoop(Global global) { - this.global = global; - int count = 0; - for (Phase p = global.PHASE.INITIAL.phase(); p != null; p = p.next) - count++; - this.phases = new Phase[count]; - this.unitss = new ArrayList[count]; - this.indexes = new int[count]; - Phase phase = global.PHASE.INITIAL.phase(); - for (int i = 0; i < count; i++) { - phases[i] = phase; - unitss[i] = new ArrayList(); - phase = phase.next; - } - } - - //######################################################################## - // Public Methods - - /** - * Compiles the given units and returns list of all compiled units - * including those loaded automatically. - */ - public CompilationUnit[] compile(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) unitss[0].add(units[i]); - int limit = phases.length - 1; - loop(limit, true); - return global.reporter.errors() != 0 - ? new CompilationUnit[0] - : (CompilationUnit[])unitss[limit].toArray( - new CompilationUnit[unitss[limit].size()]); - } - - /** - * Inserts the given unit and compiles it up to the current phase - * excluded. - */ - public void insert(CompilationUnit unit) { - Phase backup = global.currentPhase; - unitss[0].add(unit); - // !!! This "false" may be dangerous; it may lead to crashes - // because phases might work on trees/symbol-tables that - // contain errors (however this occurs only if the newly - // loaded code may contain errors). On the other hand "true", - // might starve some phases; if a phase requests a compilation - // unit, it may never receive it. - loop(getPhaseIndex(backup), false); - global.currentPhase = backup; - } - - //######################################################################## - // Private Methods - - /** Compiles all units up to phase "phases[limit]" excluded. */ - private void loop(int limit, boolean main) { - assert limit < phases.length: Debug.show(""+limit, phases); - for (int current = getFirstNonEmptyIndex(); current < limit; ) { - // !!! remove NAMER test ? - if (main && global.reporter.errors() != 0 - && global.currentPhase != global.PHASE.NAMER.phase()) break; - // Update the current phase pointer. - Phase phase = global.currentPhase = phases[current]; - // If the phase is not yet started, start it. - if (indexes[current] == 0) global.timer.start(); - // Apply the phase to all available units. It's important - // to not cache the result of "size()" as new units may be - // added during the loop. - for (int i = indexes[current]; i < unitss[current].size(); i++) - phase.apply((CompilationUnit)unitss[current].get(i)); - int next = getFirstNonEmptyIndex(); - // If no new units were introduced, stop the phase. - if (next == current) { - PhaseDescriptor descriptor = phase.descriptor; - global.timer.stop(descriptor.taskDescription()); - CompilationUnit[] units = - (CompilationUnit[])unitss[current].toArray( - new CompilationUnit[unitss[current].size()]); - if (descriptor.hasPrintFlag()) global.print(units); - // if (descriptor.hasGraphFlag()); // !!! - // if (descriptor.hasCheckFlag()); // !!! - if (phase == global.PHASE.PARSER.phase()) global.fix1(units); - if (phase == global.PHASE.ANALYZER.phase()) global.fix2(units); - unitss[current + 1].addAll(unitss[current]); - unitss[current].clear(); - next++; - } - indexes[current] = unitss[current].size(); - current = next; - } - } - - /** - * Returns the first index with a non-empty unit list. If there is - * no such index, returns "phases.length". - */ - private int getFirstNonEmptyIndex() { - int index = 0; - while (index < phases.length && unitss[index].isEmpty()) index++; - return index; - } - - /** Returns the index of the given phase. */ - private int getPhaseIndex(Phase phase) { - for (int index = 0; index < phases.length; index++) - if (phases[index] == phase) return index; - throw Debug.abort("phase not found", Debug.show(phase, phases)); - } - - //######################################################################## -} diff --git a/sources/scalac/CompilationUnit.java b/sources/scalac/CompilationUnit.java deleted file mode 100644 index 44e131bed7..0000000000 --- a/sources/scalac/CompilationUnit.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac; - -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -import scalac.ast.Tree; -import scalac.atree.ARepository; -import scalac.util.FreshNameCreator; -import java.util.HashMap; - - -/** A representation for a compilation unit in scala - * - * @author Matthias Zenger - * @version 1.0 - */ -public class CompilationUnit { - - /** the global compilation environment - */ - public final Global global; - - /** the associated source code file - */ - public final SourceFile source; - - /** does this unit come from the interpreter console - */ - public final boolean console; - - /** is this unit only there for mixin expansion? - */ - public final boolean mixinOnly; - - /** the fresh name creator - */ - public final FreshNameCreator fresh; - - /** the content of the compilation unit in tree form - */ - public Tree[] body; - public ARepository repository; - - public CompilationUnit(Global global, SourceFile source, - boolean console, boolean mixinOnly) { - this.global = global; - this.source = source; - this.console = console; - this.mixinOnly = mixinOnly; - this.fresh = new FreshNameCreator(); - } - - public CompilationUnit(Global global, SourceFile source, boolean console) { - this(global, source, console, false); - } - - /** return the position representing the given encoded position - */ - public Position position(int pos) { - return new Position(source, pos); - } - - /** issue an error in this compilation unit at a specific location - */ - public void error(int pos, String message) { - global.reporter.error(position(pos), message); - } - - /** issue a warning in this compilation unit at a specific location - */ - public void warning(int pos, String message) { - global.reporter.warning(position(pos), message); - } - - /** return a string representation - */ - public String toString() { - return source.toString(); - } - -} diff --git a/sources/scalac/CompilerCommand.java b/sources/scalac/CompilerCommand.java deleted file mode 100644 index ba016b24e6..0000000000 --- a/sources/scalac/CompilerCommand.java +++ /dev/null @@ -1,369 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import scala.tools.util.ClassPath; -import scala.tools.util.Reporter; -import scala.tools.util.ConsoleReporter; - -import scalac.util.CommandParser; -import scalac.util.ArgumentParser; -import scalac.util.OptionParser; -import scalac.util.BooleanOptionParser; -import scalac.util.StringOptionParser; -import scalac.util.ChoiceOptionParser; -import scalac.util.HelpOptionParser; -import scalac.util.VersionOptionParser; -//import scalac.util.OptimizeOptionParser; -import scalac.util.PhaseSetOptionParser; -import scalac.util.PrintOptionParser; -import scalac.util.UnknownOptionParser; -import scalac.util.ScalaFileArgumentParser; -import scalac.util.UnknownArgumentParser; -import scalac.util.Strings; - -/** - * Class <code>CompilerCommand</code> describes the options - * passed as arguments to the compiler command. - */ -public class CompilerCommand extends CommandParser { - - //######################################################################## - // Public Fields - - public final CompilerPhases phases; - - public final BooleanOptionParser debuginfo; - public final BooleanOptionParser nowarn; - public final BooleanOptionParser verbose; - public final BooleanOptionParser debug; - public final BooleanOptionParser explaintypes; - public final BooleanOptionParser uniqid; - public final BooleanOptionParser types; - public final BooleanOptionParser prompt; - public final ChoiceOptionParser separate; - //public final OptimizeOptionParser optimize; - public final StringOptionParser classpath; - public final StringOptionParser sourcepath; - public final StringOptionParser bootclasspath; - public final StringOptionParser extdirs; - public final StringOptionParser outpath; - public final StringOptionParser encoding; - public final StringOptionParser assemrefs; - public final StringOptionParser assemname; - public final ChoiceOptionParser target; - public final BooleanOptionParser noimports; - public final BooleanOptionParser nopredefs; - public final PhaseSetOptionParser skip; - public final PhaseSetOptionParser check; - public final PrintOptionParser print; - public final ChoiceOptionParser printer; - public final StringOptionParser printfile; - public final PhaseSetOptionParser graph; - public final PhaseSetOptionParser stop; - public final PhaseSetOptionParser log; - public final VersionOptionParser version; - public final HelpOptionParser help; - public final UnknownOptionParser unknown_options; - public final ScalaFileArgumentParser files; - public final UnknownArgumentParser unknown_arguments; - - /* - * Non-standard options (starting with prefix "-X") - * are subject to change without notice. - */ - public final BooleanOptionParser Xshortname; - public final BooleanOptionParser Xmarkup; - public final BooleanOptionParser Xnewmatch; - public final BooleanOptionParser XpreserveWS; - public final BooleanOptionParser XrunTimeTypes; - - /* - * Whole-program optimization options - */ - public final StringOptionParser XrootClass; - public final StringOptionParser XappFile; - public final StringOptionParser XdotFile; - public final BooleanOptionParser Xrta; - public final BooleanOptionParser Xinline; - - //######################################################################## - // Public Constructors - - /** - * Creates an instance variable. - * - * @param product - * @param version - * @param reporter - * @param phases - */ - public CompilerCommand(String product, String version, - Reporter reporter, CompilerPhases phases) - { - this(product, version, "<source files>", reporter, phases); - } - - protected CompilerCommand(String product, String version, String syntax, - Reporter reporter, CompilerPhases phases) - { - super(product, version, syntax, reporter); - this.phases = phases; - - ArgumentParser[] parsers = new ArgumentParser[] { - - this.debuginfo = new BooleanOptionParser(this, - "g", "Generate debugging info", false), - - this.nowarn = new BooleanOptionParser(this, - "nowarn", "Generate no warnings", - false), - - this.verbose = new BooleanOptionParser(this, - "verbose", "Output messages about what the compiler is doing", - false), - - //this.optimize = new OptimizeOptionParser(this, - // "optimize", "optimize bytecode (-optimize:help for option list)", - // null /* todo: uncomment: phases.OPTIMIZE */), - - this.classpath = new StringOptionParser(this, - "classpath", "Specify where to find user class files", - "path", ClassPath.DEFAULT_CLASSPATH), - - this.sourcepath = new StringOptionParser(this, - "sourcepath", "Specify where to find input source files", - "path", ClassPath.DEFAULT_SOURCEPATH), - - this.bootclasspath = new StringOptionParser(this, - "bootclasspath", "Override location of bootstrap class files", - "path", ClassPath.DEFAULT_BOOTCLASSPATH), - - this.extdirs = new StringOptionParser(this, - "extdirs", "Override location of installed extensions", - "dirs", ClassPath.DEFAULT_EXTDIRS), - - this.outpath = new StringOptionParser(this, - "d", "Specify where to place generated class files", - "directory", "."), - - this.encoding = new StringOptionParser(this, - "encoding", "Specify character encoding used by source files", - "encoding", System.getProperty("file.encoding", "ISO-8859-1")), - - this.separate = new ChoiceOptionParser(this, - "separate", "Read symbol files for separate compilation: (yes, no)", - "separate", new String[]{"yes", "no"}, "default"), - - this.target = new ChoiceOptionParser(this, - "target", "Specify which backend to use (jvm, msil)", - "target", Global.TARGETS, Global.TARGET_JVM), - - this.assemrefs = new StringOptionParser(this, "r", - "Assemblies referenced by the source program (only relevant with '-target:msil')", - "assembly files", "."), - - this.assemname = new StringOptionParser(this, "o", - "Name of the output assembly (only relevant with '-target:msil')", - "assembly name", null), - - this.debug = new BooleanOptionParser(this, - "debug", "Output debugging messages", - false), - - this.explaintypes = new BooleanOptionParser(this, - "explaintypes", "Explain type errors in more detail", - false), - - this.uniqid = new BooleanOptionParser(this, - "uniqid", "Print identifiers with unique names (debugging option)", - false), - - this.types = new BooleanOptionParser(this, - "types", "Print tree types (debugging option)", - false), - - this.prompt = new BooleanOptionParser(this, - "prompt", "Display a prompt after each error (debugging option)", - false), - - this.noimports = new BooleanOptionParser(this, - "noimports", "Compile without any implicit imports", - false), - - this.nopredefs = new BooleanOptionParser(this, - "nopredefs", "Compile without any implicit predefined values", - false), - - this.skip = new PhaseSetOptionParser(this, - "skip", "Skip <phases> (see below)", - phases.phases(), PhaseDescriptor.SKIP), - - this.check = new PhaseSetOptionParser(this, - "check", "Check the tree after <phases> (see below)", - phases.phases(), PhaseDescriptor.CHECK), - - this.print = new PrintOptionParser(this, - "print", "Print out program after <phases> (see below)", - phases.phases(), PhaseDescriptor.PRINT), - - this.printer = new ChoiceOptionParser(this, - "printer", "Printer to use", - "printer", Global.PRINTERS, Global.PRINTER_TEXT), - - this.printfile = new StringOptionParser(this, - "print-file", "Specify file in which to print trees", - "file", "-"), - - this.graph = new PhaseSetOptionParser(this, - "graph", "Graph the program after <phases> (see below)", - phases.phases(), PhaseDescriptor.GRAPH), - - this.stop = new PhaseSetOptionParser(this, - "stop", "Stop after first phase in <phases> (see below)", - phases.phases(), PhaseDescriptor.STOP), - - this.log = new PhaseSetOptionParser(this, - "log", "Log operations in <phases> (see below)", - phases.phases(), PhaseDescriptor.LOG), - - this.version = new VersionOptionParser(this, - "version", "Print product version and exit", - product() + " " + version() + " -- (c) 2002-05 LAMP/EPFL"), - - this.help = new HelpOptionParser(this, - "help", "Print a synopsis of standard options"), - - this.Xshortname = new BooleanOptionParser(this, - "Xshortname", "Display short file names in error reports", - false), - - this.Xmarkup = new BooleanOptionParser(this, - "Xmarkup", "no effect, only for compatibility", - false), - - this.Xnewmatch = new BooleanOptionParser(this, - "Xnewmatch", "new pattern matching", - false), - - this.XpreserveWS = new BooleanOptionParser(this, - "XpreserveWS", "don't trim whitespace in XML literals", - false), - - this.XrootClass = new StringOptionParser(this, - "XrootClass", "Specify the root class of the global application", - "class", "$"), - - this.XappFile = new StringOptionParser(this, - "XappFile", "Specify the filename where to dump the whole-application inferred from the rootclass", - "file", "app.txt"), - - this.XdotFile = new StringOptionParser(this, - "XdotFile", "Specify the filename where to print the AST in graphviz dot format", - "file", "$"), - - this.Xrta = new BooleanOptionParser(this, - "Xrta", "Perform Rapid Type analysis for method call resolution", - false), - - this.Xinline = new BooleanOptionParser(this, - "Xinline", "Inline method calls that can be resolved statically", - false), - - this.XrunTimeTypes = new BooleanOptionParser(this, - "Xrtt", "Enable run-time types", - false), - - this.unknown_options = new UnknownOptionParser(this), - - this.files = new ScalaFileArgumentParser(this), - - this.unknown_arguments = new UnknownArgumentParser(this), - - }; - - for (int i = 0; i < parsers.length; i++) add(parsers[i]); - } - - //######################################################################## - // Public Methods - - /** - * .. - * - * @param args - */ - public boolean parse(String[] args) { - boolean result = super.parse(args); - reporter().verbose(verbose.value); - reporter().nowarn(nowarn.value); - reporter().prompt(prompt.value); - if (reporter() instanceof ConsoleReporter) - ((ConsoleReporter)reporter()).shortname = Xshortname.value; - return result; - } - - private boolean containsPhaseOptions() { - List parsers = parsers(); - for (int i = 0; i < parsers.size(); i++) { - if (parsers.get(i) instanceof PhaseSetOptionParser) return true; - } - return false; - } - - /** - * Returns the help message for this compiler command. - * - * @return a formatted string containing the help message. - */ - public String getHelpMessage() { - StringBuffer buffer = new StringBuffer(super.getHelpMessage()); - if (containsPhaseOptions()) { - buffer.append(Strings.EOL); - buffer.append("and possible compilation phases include:"); - buffer.append(Strings.EOL); - PhaseDescriptor[] array = phases.phases(); - List lines = new ArrayList(array.length); - for (int i = 0; i < array.length; i++) { - PhaseDescriptor phase = array[i]; - lines.add(" " + phase.name() + "\t " + phase.description()); - } - lines.add(" " + "all" + "\t " + "matches all phases"); - buffer.append(Strings.format(lines)); - } - return buffer.toString(); - } - - /** - * Returns the class path for this compiler command. - * - * @return the class path. - */ - public ClassPath classpath() { - return new ClassPath(classpath.value, sourcepath.value, - bootclasspath.value, extdirs.value); - } - - /** - * Returns the output path for this compiler command. - * - * @return the output path terminated by . - */ - public String outpath() { - return outpath.value + ( - outpath.value.endsWith(File.separator) ? "" : File.separator - ); - } - - //######################################################################## -} diff --git a/sources/scalac/CompilerPhases.java b/sources/scalac/CompilerPhases.java deleted file mode 100644 index 3440f9bf75..0000000000 --- a/sources/scalac/CompilerPhases.java +++ /dev/null @@ -1,231 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import java.util.ArrayList; -import java.util.List; - -/** - * This class defines all compiler phases and maintains a list of - * active phases. - */ -public abstract class CompilerPhases { - - //######################################################################## - // Public Fields - - /** The compiler phases. */ - public final PhaseDescriptor INITIAL; - public final PhaseDescriptor PARSER; - public final PhaseDescriptor NAMER; - public final PhaseDescriptor ANALYZER; - public final PhaseDescriptor REFCHECK; - public final PhaseDescriptor UNCURRY; - // public final PhaseDescriptor OPTIMIZE; - public final PhaseDescriptor TAILCALL; // Moved here experimentally - - public final PhaseDescriptor TRANSMATCH; - public final PhaseDescriptor LAMBDALIFT; - public final PhaseDescriptor ADDACCESSORS; - public final PhaseDescriptor EXPLICITOUTER; - public final PhaseDescriptor ADDCONSTRUCTORS; - public final PhaseDescriptor TYPESASVALUES; - - public final PhaseDescriptor WHOLEPROG; - public final PhaseDescriptor ADDINTERFACES; - public final PhaseDescriptor EXPANDMIXIN; - public final PhaseDescriptor MAKEBOXINGEXPLICIT; - public final PhaseDescriptor ERASURE; - public final PhaseDescriptor ICODE; - public final PhaseDescriptor CODEGEN; - public final PhaseDescriptor TERMINAL; - - //######################################################################## - // Private Fields - - /** The list containing the active phases */ - private final List phases; - - /** Phase names, can be overridden to install . - */ - protected abstract Class PARSER_PHASE(); - protected abstract Class NAMER_PHASE(); - protected abstract Class ANALYZER_PHASE(); - protected abstract Class REFCHECK_PHASE(); - protected abstract Class UNCURRY_PHASE(); - protected abstract Class TRANSMATCH_PHASE(); - protected Class LAMBDALIFT_PHASE() { return scalac.transformer.LambdaLiftPhase.class; } - protected Class EXPLICITOUTER_PHASE() { return scalac.transformer.ExplicitOuterClassesPhase.class; } - protected Class ADDACCESSORS_PHASE() { return scalac.transformer.AddAccessorsPhase.class; } - protected Class ADDCONSTRUCTORS_PHASE() { return scalac.transformer.AddConstructorsPhase.class; } - protected Class TYPESASVALUES_PHASE() { return scalac.transformer.TypesAsValuesPhase.class; } - protected Class TAILCALL_PHASE() { return scalac.transformer.TailCallPhase.class; } - protected abstract Class WHOLEPROG_PHASE(); - protected Class ADDINTERFACES_PHASE() { return scalac.transformer.AddInterfacesPhase.class; } - protected Class EXPANDMIXIN_PHASE() { return scalac.transformer.ExpandMixinsPhase.class; } - protected Class ERASURE_PHASE() { return scalac.transformer.ErasurePhase.class; } - protected abstract Class ICODE_PHASE(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public CompilerPhases() { - this.phases = new ArrayList(); - PhaseDescriptor[] array = { - this.INITIAL = new PhaseDescriptor( - "initial", - "initializing compiler", - "initializing compiler", - scalac.util.EmptyPhase.class), - this.PARSER = new PhaseDescriptor( - "parse", - "parse source files", - "parsed", - PARSER_PHASE()), - this.NAMER = new PhaseDescriptor( - "namer", - "create symbols", - "symbols created", - NAMER_PHASE()), - this.ANALYZER = new PhaseDescriptor( - "analyze", - "name and type analysis", - "type checking", - ANALYZER_PHASE()), - this.REFCHECK = new PhaseDescriptor( - "refcheck", - "reference checking", - "reference checking", - REFCHECK_PHASE()), - this.UNCURRY = new PhaseDescriptor( - "uncurry", - "uncurry function types and applications", - "uncurried", - UNCURRY_PHASE()), -// this.OPTIMIZE = new PhaseDescriptor( -// "optimize", -// "tree-optimizer", -// "tree optimization", -// scalac.optimizer.OptimizePhase.class), - - this.TAILCALL = new PhaseDescriptor( - "tailcall", - "add tail-calls", - "added tail-calls", - TAILCALL_PHASE()), - - this.TRANSMATCH = new PhaseDescriptor( - "transmatch", - "translate match expressions", - "translated pattern matching", - TRANSMATCH_PHASE()), - this.TYPESASVALUES = new PhaseDescriptor( - "typesasvalues", - "represent types as values", - "represented types as values", - TYPESASVALUES_PHASE()), - this.LAMBDALIFT = new PhaseDescriptor( - "lambdalift", - "lambda lifter", - "lambda lifting", - LAMBDALIFT_PHASE()), - this.ADDACCESSORS = new PhaseDescriptor( - "addaccessors", - "add accessors for constructor arguments", - "added accessors", - ADDACCESSORS_PHASE()), - this.EXPLICITOUTER = new PhaseDescriptor( - "explicitouterclasses", - "make links from inner classes to enclosing one explicit", - "made outer links explicit", - EXPLICITOUTER_PHASE()), - this.ADDCONSTRUCTORS = new PhaseDescriptor( - "addconstructors", - "add explicit constructor for each class", - "added constructors", - ADDCONSTRUCTORS_PHASE()), - this.WHOLEPROG = new PhaseDescriptor( - "wholeprog", - "perform whole program analysis", - "find monomorphic callsites and performs inlining", - WHOLEPROG_PHASE()), - this.ADDINTERFACES = new PhaseDescriptor( - "addinterfaces", - "add one interface per class", - "added interfaces", - ADDINTERFACES_PHASE()), - this.EXPANDMIXIN = new PhaseDescriptor( - "expandmixins", - "expand mixins by code copying", - "expanded mixins", - EXPANDMIXIN_PHASE()), - this.MAKEBOXINGEXPLICIT = new PhaseDescriptor( - "boxing", - "makes boxing explicit", - "made boxing explicit", - scalac.transformer.MakeBoxingExplicitPhase.class), - this.ERASURE = new PhaseDescriptor( - "erasure", - "type eraser", - "erased types", - ERASURE_PHASE()), - this.ICODE = new PhaseDescriptor( - "icode", - "generate icode", - "generated icode", - ICODE_PHASE()), - this.CODEGEN = new PhaseDescriptor( - "codegen", - "enable code generation", - "code generation enabled", - scalac.util.EmptyPhase.class), - this.TERMINAL = new PhaseDescriptor( - "terminal", - "compilation terminated", - "compilation terminated", - scalac.util.EmptyPhase.class), - }; - for (int i = 0; i < array.length; i++) phases.add(array[i]); - } - - //######################################################################## - // Public Methods - - /** Returns an array containing all active phases. */ - public PhaseDescriptor[] phases() { - PhaseDescriptor[] array = new PhaseDescriptor[phases.size()]; - phases.toArray(array); - return array; - } - - /** Freezes all active phases. */ - public void freeze() { - PhaseDescriptor[] phases = phases(); - PhaseDescriptor.freeze(phases); - } - - /** Activates phase "phase" by placing it before phase "where". */ - public int insertBefore(PhaseDescriptor phase, PhaseDescriptor where) { - int index = phases.indexOf(where); - assert index >= 0 : "could not find phase " + where; - phases.add(index, phase); - return index; - } - - /** Activates phase "phase" by placing it after phase "where". */ - public int insertAfter(PhaseDescriptor phase, PhaseDescriptor where) { - int index = phases.indexOf(where); - assert index >= 0 : "could not find phase " + where; - phases.add(index + 1, phase); - return index + 1; - } - - //######################################################################## -} diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java deleted file mode 100644 index 801883ad25..0000000000 --- a/sources/scalac/Global.java +++ /dev/null @@ -1,706 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac; - -import ch.epfl.lamp.util.CodePrinter; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.UnsupportedCharsetException; -import java.util.*; - -import scala.tools.util.AbstractFile; -import scala.tools.util.ClassPath; -import scala.tools.util.Position; -import scala.tools.util.SourceFile; -import scala.tools.util.SourceReader; -import scala.tools.util.Reporter; -import scala.tools.util.Timer; -import scala.tools.util.DummyTimer; -import scala.tools.util.ReporterTimer; - -import scalac.ast.*; -import scalac.ast.parser.*; -import scalac.ast.printer.TreePrinter; -import scalac.atree.AConstant; -import scalac.atree.ATreePrinter; -import scalac.backend.Primitives; -// !!! <<< Interpreter stuff -import scalac.symtab.*; -// !!! >>> Interpreter stuff -import scalac.symtab.Definitions; -import scalac.symtab.classfile.PackageParser; -import scalac.symtab.classfile.CLRPackageParser; -import scalac.typechecker.AnalyzerPhase; -import scalac.typechecker.Infer; -import scalac.transformer.ICodePhase; -import scalac.util.*; - -/** The global environment of a compiler run - * - * @author Matthias Zenger - * @version 1.0 - */ -public abstract class Global { - - public static Global instance; - - /** global options - */ - public final boolean noimports; - public final boolean nopredefs; - public final boolean separate; - //public final boolean optimize; - public final boolean debug; - public final boolean debuginfo; - public final boolean explaintypes; - public final boolean uniqid; - public final boolean newMatch; - public final boolean xmlPreserveWS; - public final boolean runTimeTypes; - - public final boolean printtypes; - public final boolean printtokens; - - public final String outpath; - public final String encoding; - public final String target; - - /** the message reporter - */ - public final Reporter reporter; - - /** the timer - */ - public final Timer timer; - - /** the source file charset - */ - private final Charset charset; - - /** the source file decoder - */ - private final CharsetDecoder decoder; - - /** the source file reader - */ - private final SourceReader reader; - - /** the class path - */ - public final ClassPath classPath; - - /** the global tree factory - */ - public final TreeFactory make; - - /** the tree generator - */ - public final TreeGen treeGen; - - /** the global tree printer - */ - public final PrintWriter writer; - public final TreePrinter treePrinter; - - /** documentation comments of symbols - */ - public final Map/*<Symbol, String>*/ mapSymbolComment = new HashMap(); - - /** attributes of symbols - */ - protected final Map/*<Symbol, AttributeInfo>*/ mapSymbolAttr = new HashMap(); - - /** views associated with (upper-bounded) type parameters - */ - public final Map/*<Symbol, Symbol>*/ viewOfTypeParam = new HashMap(); - - /** Pickled info of top-level symbols - */ - public final Map/*<Symbol, Pickle>*/ symdata = new HashMap(); - - - /** The compiler command arguments - */ - public final CompilerCommand args; - - /** The set of currently compiled top-level symbols - */ - public HashMap/*<Symbol,Sourcefile>*/ compiledNow = new HashMap(); - - /** The set of already compiled sourcefiles - */ - private HashSet/*<SourceFile>*/ compiledUnits = new HashSet(); - - /** the current phase - */ - public Phase currentPhase; - - /** the global definitions - */ - public Definitions definitions; - - /** the global primitives - */ - public final Primitives primitives; - - /** compilation phases. - */ - public final CompilerPhases PHASE; - - /** The current compilation loop or null */ - private CompilationLoop loop; - - /** compilation targets - */ - public static final String TARGET_INT; - public static final String TARGET_JVM; - public static final String TARGET_MSIL; - public static final String TARGET_JVMFROMICODE; - - public static final String[] TARGETS = new String[] { - TARGET_INT = "int", - TARGET_JVM = "jvm", - TARGET_MSIL = "msil", - TARGET_JVMFROMICODE = "jvmfromicode" - }; - - /** tree printers - */ - public static final String PRINTER_TEXT; - public static final String PRINTER_HTML; - public static final String PRINTER_SWING; - - public static final String[] PRINTERS = new String[] { - PRINTER_TEXT = "text", - PRINTER_HTML = "html", - PRINTER_SWING = "swing", - }; - - public static Timer getTimer(Reporter reporter) { - return reporter.verbose() - ? (Timer)new ReporterTimer(reporter) - : (Timer)DummyTimer.object; - } - - /** hooks for installing printers - */ - public abstract Infer newInfer(); - public abstract TreePrinter newTextTreePrinter(PrintWriter writer); - public abstract TreePrinter newHTMLTreePrinter(PrintWriter writer); - public abstract TreePrinter newSwingTreePrinter(PrintWriter writer); - - /** - * Creates an instance variable. - * - * @param args - * @param interpret - */ - public Global(CompilerCommand args, Timer timer, boolean interpret) { - assert Debug.initialize() || true; - if (Global.instance != null) // jaco bug: can't use assert here - /* throw */ Debug.abort("duplicate creation of Global"); - Global.instance = this; - this.args = args; - this.reporter = args.reporter(); - this.timer = timer; - this.noimports = args.noimports.value; - this.nopredefs = args.nopredefs.value; - //this.optimize = args.optimize.optimize; - this.debug = args.debug.value; - this.debuginfo = args.debuginfo.value; - this.uniqid = args.uniqid.value; - this.newMatch = args.Xnewmatch.value; - this.xmlPreserveWS = args.XpreserveWS.value; - this.runTimeTypes = args.XrunTimeTypes.value; - this.explaintypes = args.explaintypes.value; - this.printtypes = args.types.value; - this.printtokens = args.print.tokens; - this.classPath = args.classpath(); - reporter.info(null, "classpath = " + classPath, false); - this.outpath = args.outpath(); - String encoding = args.encoding.value; - Charset charset = null; - try { - charset = Charset.forName(encoding); - } catch (IllegalCharsetNameException exception) { - args.encoding.error("illegal charset name '" + encoding + "'"); - } catch (UnsupportedCharsetException exception) { - args.encoding.error("unsupported charset '" + encoding + "'"); - } - if (charset == null) { - encoding = "ISO-8859-1"; // A mandatory charset - charset = Charset.forName(encoding); - } - this.encoding = encoding; - this.charset = charset; - this.decoder = charset.newDecoder(); - this.reader = new SourceReader(decoder); - this.target = interpret ? TARGET_INT : args.target.value.intern(); - this.separate = args.separate.value.equals("yes") || - args.separate.value.equals("default") && !this.target.equals(TARGET_INT); - String printFile = args.printfile.value; - OutputStream stream; - try { - stream = "-".equals(printFile) - ? System.out - : new FileOutputStream(printFile); - } catch (FileNotFoundException e) { - error("unable to open file " + printFile + ". Printing on console"); - stream = System.out; - } - this.writer = new PrintWriter(stream, debug); - if (args.printer.value.equals(PRINTER_HTML)) { - this.treePrinter = newHTMLTreePrinter(writer); - } else if (args.printer.value.equals(PRINTER_SWING)) { - this.treePrinter = newSwingTreePrinter(writer); - } else { - if (!args.printer.value.equals(PRINTER_TEXT)) - error("unknown printer kind: " + args.printer.value); - this.treePrinter = newTextTreePrinter(writer); - } - this.make = new DefaultTreeFactory(); - this.PHASE = args.phases; - args.phases.WHOLEPROG.addSkipFlag(); // !!! - // if (!optimize) PHASE.remove(args.phases.OPTIMIZE); - // TODO: Enable TailCall for other backends when they handle LabelDefs - if (target != TARGET_JVMFROMICODE) args.phases.ICODE.addSkipFlag(); - PHASE.freeze(); - PhaseDescriptor[] descriptors = PHASE.phases(); - int i = 0; - for (; i < descriptors.length; i++) { - if (!descriptors[i].hasSkipFlag()) descriptors[i].create(this); - if (descriptors[i] == PHASE.ANALYZER) { i++; break; } - } - this.treeGen = ((AnalyzerPhase)PHASE.ANALYZER.phase()).gen; - this.primitives = new Primitives(this); - for (; i < descriptors.length; i++) - if (!descriptors[i].hasSkipFlag()) descriptors[i].create(this); - assert descriptors.length >= 2 - && descriptors[0] == PHASE.INITIAL - && descriptors[descriptors.length - 1] == PHASE.TERMINAL: - Debug.show(descriptors); - assert !PHASE.INITIAL.hasSkipFlag(); - this.currentPhase = PHASE.INITIAL.phase(); - } - - /** - * Moves to next phase. - */ - public void nextPhase() { - assert currentPhase.next != null; - currentPhase = currentPhase.next; - } - - /** Move to previous phase - */ - public void prevPhase() { - assert currentPhase.prev != null; - currentPhase = currentPhase.prev; - } - - /** Creates a virtual source file with given name and content. */ - public SourceFile getSourceFile(String sourcename, String content) { - return new SourceFile(sourcename, content.toCharArray()); - } - - /** Reads and returns the source file in file with given name. */ - public SourceFile getSourceFile(String filename) throws IOException { - AbstractFile file = AbstractFile.getFile(filename); - if (file == null) throw new FileNotFoundException( - "source file '" + filename + "' could not be found"); - return getSourceFile(file); - } - - /** Reads and returns the source file in given abstract file. */ - public SourceFile getSourceFile(AbstractFile file) throws IOException { - return new SourceFile(file, reader.read(file)); - } - - /** Reads and returns the source file of given clasz. */ - public SourceFile getSourceFile(Symbol clasz) throws IOException { - assert clasz.isClass() && clasz.isStatic(): Debug.show(clasz); - AbstractFile file = classPath.getRoot().lookupPath( - SourceRepresentation.externalizeFileName(clasz, ".scala"), false); - if (file == null) throw new FileNotFoundException( - "source file for " + clasz + " could not be found"); - return getSourceFile(file); - } - - /** Returns the root symbol loader. */ - public SymbolLoader getRootLoader() { - return target == TARGET_MSIL - ? new CLRPackageParser(this, classPath.getRoot()) - : new PackageParser(this, classPath.getRoot()); - } - - /** the top-level compilation process - */ - public CompilationUnit[] compile(String[] files, boolean console) { - reporter.resetCounters(); - // parse files - List units = new ArrayList(files.length); - for (int i = 0; i < files.length; i++) { - try { - SourceFile source = getSourceFile(files[i]); - units.add(new CompilationUnit(this, source, console)); - compiledUnits.add(source); - } catch (IOException exception) { - error("IO problem (encoding problem?) with file "+files[i] - +"\n exception was: "+exception.getMessage()); - } - } - CompilationUnit[] array = new CompilationUnit[units.size()]; - return compile((CompilationUnit[])units.toArray(array)); - } - - /** - * The top-level compilation process. - * - * @param filename - * @param input - * @param console - */ - public CompilationUnit[] compile(String filename, String input, boolean console) { - reporter.resetCounters(); - SourceFile source = getSourceFile(filename, input); - compiledUnits.add(source); - CompilationUnit[] units = {new CompilationUnit(this, source, console)}; - return compile(units); - } - - /** compile all compilation units - */ - private CompilationUnit[] compile(CompilationUnit[] units) { - this.currentPhase = PHASE.INITIAL.phase(); - treePrinter.begin(); - this.loop = new CompilationLoop(this); - loadFunctions(); - units = loop.compile(units); - this.loop = null; - if (reporter.errors() != 0) { - imports.clear(); - for (Iterator i = compiledNow.entrySet().iterator(); i.hasNext();) { - Map.Entry entry = (Map.Entry)i.next(); - Symbol clasz = (Symbol)entry.getKey(); - AbstractFile file = ((SourceFile)entry.getValue()).getFile(); - clasz.reset(new SourceCompleter(this, file)); - } - } - compiledNow.clear(); - treePrinter.end(); - this.currentPhase = PHASE.TERMINAL.phase(); - return units; - } - - protected abstract void loadFunctions(); - - /** Compiles an additional source file. */ - public void compileLate(SourceFile source, boolean mixinOnly) { - assert loop != null: source; - if (!compiledUnits.contains(source)) { - compiledUnits.add(source); - CompilationUnit unit = new CompilationUnit(this, source, false, mixinOnly); - loop.insert(unit); - } - } - - - /** Add attribute for a symbol - * @param sym - symbol of the defininition to which the attribute is applied - * @param aSym - symbol of the constructor of the attribute class - * @param args - arguments to the attribute constructor - */ - public void addAttribute(Symbol sym, Symbol aSym, AConstant[] args) { - if (aSym != null && ! (aSym.isNone() || aSym.isError())) { - AttributeInfo attr = getAttributes(sym); - attr = new AttributeInfo(aSym, args, attr); - setAttribute(sym, attr); - } - } - - /** Add attribute with no arguments - * @param sym - symbol of the defininition to which the attribute is applied - * @param aSym - symbol of the constructor of the attribute class - */ - public void addAttribute(Symbol sym, Symbol aSym) { - addAttribute(sym, aSym, AConstant.EMPTY_ARRAY); - } - - /** Set the attributes for a given symbol - */ - public void setAttribute(Symbol sym, AttributeInfo attr) { - mapSymbolAttr.put(sym, attr); - if (sym.isModule() && !sym.isModuleClass()) - mapSymbolAttr.put(sym.moduleClass(), attr); - } - - /** Return all attributes for a given symbol - */ - public AttributeInfo getAttributes(Symbol sym) { - return (AttributeInfo)mapSymbolAttr.get(sym); - } - - /** Return attribute arguments - * @param sym - symbol of the definition - * @param aSym - symbol of the constructor of the attribute class - */ - public AConstant[] getAttrArguments(Symbol sym, Symbol aSym) { - AttributeInfo attrs = getAttributes(sym); - return attrs == null ? null : attrs.getAttrArguments(aSym); - } - - /** Remove the attributes for a given symbol - */ - public AttributeInfo removeAttributes(Symbol sym) { - return (AttributeInfo)mapSymbolAttr.remove(sym); - } - - public abstract void dump(CompilationUnit[] units); - - void print(CompilationUnit[] units) { - if (currentPhase.id == PHASE.MAKEBOXINGEXPLICIT.id()) { - boolean html = args.printer.value.equals(PRINTER_HTML); - if (html) writer.println("<pre>"); - ATreePrinter printer = new ATreePrinter(new CodePrinter(writer)); - boolean next = currentPhase.next != null; - if (next) currentPhase = currentPhase.next; - printer.printUnits(units); - if (next) currentPhase = currentPhase.prev; - if (html) writer.println("</pre>"); - } else if (currentPhase.id == PHASE.ICODE.id()) { - Phase phase = currentPhase; - boolean html = args.printer.value.equals(PRINTER_HTML); - if (html) writer.println("<pre>"); - - boolean next = currentPhase.next != null; - if (next) currentPhase = currentPhase.next; - ((ICodePhase)phase).print(units, new CodePrinter(writer)); - if (next) currentPhase = currentPhase.prev; - if (html) writer.println("</pre>"); - } else { - // go to next phase to print symbols with their new type - boolean next = currentPhase.next != null; - if (next) currentPhase = currentPhase.next; - treePrinter.print(units); - if (next) currentPhase = currentPhase.prev; - } - } - - // !!! <<< Interpreter stuff - public static final String CONSOLE_S = "$console$"; - private static final Name - SHOW_DEFINITION_N = Name.fromString("showDefinition"), - SHOW_VALUE_DEFINITION_N = Name.fromString("showValueDefinition"), - SET_EVALUATION_RESULT_N = Name.fromString("setEvaluationResult"); - private Symbol INTERPRETER; - private Symbol PRINTER; - private Symbol SHOW_VALUE; - private Symbol SET_EVALUATION_RESULT; - private Symbol SHOW_DEFINITION; - private Symbol SHOW_VALUE_DEFINITION; - - private Symbol INTERPRETER() { - if (INTERPRETER == null) - INTERPRETER = definitions.getModule("scala.runtime.InterpreterSupport"); - return INTERPRETER; - } - - private Symbol SHOW_DEFINITION() { - if (SHOW_DEFINITION == null) - SHOW_DEFINITION = INTERPRETER().lookup(SHOW_DEFINITION_N); - return SHOW_DEFINITION; - } - - private Symbol SHOW_VALUE_DEFINITION() { - if (SHOW_VALUE_DEFINITION == null) - SHOW_VALUE_DEFINITION = INTERPRETER().lookup(SHOW_VALUE_DEFINITION_N); - return SHOW_VALUE_DEFINITION; - } - - private Symbol SET_EVALUATION_RESULT() { - if (SET_EVALUATION_RESULT == null) - SET_EVALUATION_RESULT = INTERPRETER().lookup(SET_EVALUATION_RESULT_N); - return SET_EVALUATION_RESULT; - } - - private int module = 0; - private List imports = new ArrayList(); - public Symbol console; - - void fix1(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) { - if (units[i].console) fix1(units[i]); - } - nextPhase(); - for (int i = 0; i < imports.size(); i++) { - Symbol module = (Symbol)imports.get(i); - ((scalac.typechecker.AnalyzerPhase)PHASE.ANALYZER.phase()).addConsoleImport(module); - } - prevPhase(); - } - - private void fix1(CompilationUnit unit) { - unit.body = new Tree[] { - make.ModuleDef(Position.FIRSTPOS, - 0, Name.fromString(CONSOLE_S+module), Tree.Empty, - make.Template(Position.FIRSTPOS, new Tree[]{ - make.Apply(Position.FIRSTPOS, - make.Select(Position.FIRSTPOS, - make.Ident(Position.FIRSTPOS, Names.scala), - Names.AnyRef.toTypeName()), - new Tree[0])}, - unit.body))}; - module++; - } - - void fix2(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) { - if (units[i].console) fix2(units[i]); - } - } - - private void fix2(CompilationUnit unit) { - imports.clear(); - for (int i = 0; i < unit.body.length; i++) { - switch (unit.body[i]) { - case ModuleDef(_, _, _, Tree.Template impl): - Symbol symbol = unit.body[i].symbol(); - if (!symbol.name.toString().startsWith(CONSOLE_S)) break; - console = symbol; - if (impl.body.length <= 0) break; - imports.add(unit.body[i].symbol()); - Tree last = impl.body[impl.body.length - 1]; - if (last != Tree.Empty && last.isTerm()) { - impl.body[impl.body.length - 1] = - treeGen.Apply(last.pos, - treeGen.Select(last.pos, - treeGen.mkGlobalRef(last.pos, INTERPRETER()), - SET_EVALUATION_RESULT()), - new Tree[] { - last, - treeGen.mkStringLit( - last.pos, show(last.getType()))}); - } - TreeList body = new TreeList(); - for (int j = 0; j < impl.body.length; j++) - fix2(body, impl.body[j]); - impl.body = body.toArray(); - break; - } - } - } - - private void fix2(TreeList body, Tree tree) { - body.append(tree); - switch (tree) { - case PatDef(_, _, _): // !!! impossible (removed by analyzer) - assert false : Debug.show(tree); - return; - case ClassDef(_, _, _, _, _, _): - case PackageDef(_, _): - case ModuleDef(_, _, _, _): - case DefDef(_, _, _, _, _, _): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - if (!mustShow(tree.symbol())) return; - body.append( - treeGen.Apply(tree.pos, - treeGen.Select(tree.pos, - treeGen.mkGlobalRef(tree.pos, INTERPRETER()), - SHOW_DEFINITION()), - new Tree[] { - treeGen.mkStringLit(tree.pos, show(tree.symbol()))})); - return; - case ValDef(_, _, _, _): - if (!mustShow(tree.symbol())) return; - body.append( - treeGen.Apply(tree.pos, - treeGen.Select(tree.pos, - treeGen.mkGlobalRef(tree.pos, INTERPRETER()), - SHOW_VALUE_DEFINITION()), - new Tree[] { - treeGen.mkStringLit(tree.pos, show(tree.symbol())), - treeGen.Ident(tree.pos, tree.symbol())})); - return; - default: - return; - } - } - - private boolean mustShow(Symbol symbol) { - return !symbol.isAccessor(); - } - - private String show(Symbol symbol) { - return new InterpreterPrinter().printSignature(symbol).toString(); - } - - private String show(Type type) { - return new InterpreterPrinter().printType(type).toString(); - } - - private class InterpreterPrinter extends SymbolTablePrinter { - public InterpreterPrinter() { - super(" "); - } - public String getSymbolName(Symbol symbol) { - String string = super.getSymbolName(symbol); - if (!debug) { - int index = string.indexOf('$'); - if (index > 0) string = string.substring(0, index); - } - return string; - } - } - - // !!! >>> Interpreter stuff - - /** issue a global error - */ - public void error(String message) { - reporter.error(null, message); - } - - /** issue a global warning - */ - public void warning(String message) { - reporter.warning(null, message); - } - - /** issue an operation note - */ - public void operation(String message) { - reporter.info(null, "[" + message + "]", false); - } - - /** issue a debug message from currentPhase - */ - // the boolean return value is here to let one write "assert log( ... )" - public boolean log(String message) { - if (log()) { - reporter.info(null, "[log " + currentPhase + "] " + message, true); - } - return true; - } - - /** return true if logging is switched on for the current phase - */ - public boolean log() { - return currentPhase.descriptor.hasLogFlag(); - } - -} diff --git a/sources/scalac/Phase.java b/sources/scalac/Phase.java deleted file mode 100644 index 5239562e9d..0000000000 --- a/sources/scalac/Phase.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -public abstract class Phase { - - //######################################################################## - // Public Fields - - /** The global environment */ - public final Global global; - - /** The phase descriptor */ - public final PhaseDescriptor descriptor; - - /** The phase identifier */ - public final int id; - - /** The previous phase */ - public final Phase prev; - - /** The next phase */ - public Phase next; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public Phase(Global global, PhaseDescriptor descriptor) { - this.global = global; - this.descriptor = descriptor; - this.id = descriptor.id(); - this.prev = global.currentPhase; - if (prev != null) prev.next = this; - descriptor.initialize(this); - global.currentPhase = this; - } - - //######################################################################## - // Public Methods - - /** Does this phase precede the given phase? */ - public boolean precedes(Phase phase) { - return id < phase.id; - } - - /** - * Returns the info of `sym' after the phase. Assumes that `tp' is - * the info of symbol `sym' before this phase. - */ - public Type transformInfo(Symbol sym, Type tp) { - return tp; - } - - /** Applies this phase to the given compilation unit. */ - public abstract void apply(CompilationUnit unit); - - /** Returns the name of this phase. */ - public final String toString() { - return descriptor.name(); - } - - //######################################################################## -} diff --git a/sources/scalac/PhaseDescriptor.java b/sources/scalac/PhaseDescriptor.java deleted file mode 100644 index c93fd327ba..0000000000 --- a/sources/scalac/PhaseDescriptor.java +++ /dev/null @@ -1,233 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -import scalac.util.Debug; - -/** - * Information about a compiler phase. - */ -public final class PhaseDescriptor { - - //######################################################################## - // Public Constants - - public static final int STOP = 0x0001; - public static final int SKIP = 0x0002; - public static final int PRINT = 0x0004; - public static final int GRAPH = 0x0008; - public static final int CHECK = 0x0010; - public static final int LOG = 0x0020; - - //######################################################################## - // Public Functions - - /** Freezes the given phases (patches flags and assigns ids). */ - public static void freeze(PhaseDescriptor[] phases) { - // there are at least two phases: INITIAL and TERMINAL - assert phases.length >= 2; - if (phases.length == 0) return; - // propagate STOP and SKIP - for (int i = 0; i < phases.length - 1; i++) { - phases[i].flags |= (phases[i + 1].flags >>> 16) & (STOP | SKIP); - phases[i+1].flags &= ~((STOP | SKIP) << 16); - } - // transform STOP flags into SKIP flags - boolean stop = false; - for (int i = 0; i < phases.length; i++) { - if (stop) phases[i].flags |= SKIP; - stop |= phases[i].hasStopFlag(); - if (stop) phases[i].flags &= ~STOP; - } - // remove SKIP flag on INITIAL and TERMINAL phases - phases[0].flags &= ~SKIP; - phases[phases.length - 1].flags &= ~SKIP; - // propagate other flags and freeze remaining phases - PhaseDescriptor last = null; - for (int i = 0; i < phases.length; i++) { - phases[i].id = 2 * i; - if (phases[i].hasSkipFlag()) continue; - if (last != null) last.flags |= phases[i].flags >>> 16; - phases[i].flags &= 0x0000FFFF; - if (i != phases.length - 1) last = phases[i]; - } - // place TERMINAL phase just after last active phase - phases[phases.length - 1].id = last.id + 1; - } - - //######################################################################## - // Private Fields - - /** The phase name */ - private final String name; - /** The phase description */ - private final String description; - /** The phase task description */ - private final String task; - /** The phase implementation class */ - private final Class clasz; - - /** The flags of this phase */ - private int flags; - /** The phase instance */ - private Phase phase; - /** The phase identifier */ - private int id = -1; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public PhaseDescriptor(String name, String description, String task, - Class clasz) - { - this.name = name; - this.description = description; - this.task = task; - this.clasz = clasz; - } - - //######################################################################## - // Public Methods - - /** Returns the one-word name of this phase. */ - public String name() { - return name; - } - - /** Returns a one-line description of this phase. */ - public String description() { - return description; - } - - /** Returns a one-line task description of this phase. */ - public String taskDescription() { - return task; - } - - /** Creates the object implementing this phase. */ - public Phase create(Global global) { - assert id >= 0 : "phase " + name + " not yet frozen"; - assert phase == null : "phase " + name + " already created"; - try { - Class[] params = { Global.class, PhaseDescriptor.class }; - Object[] args = { global, this }; - Object phase = clasz.getConstructor(params).newInstance(args); - assert this.phase == phase: this.phase + " != " + phase; - return this.phase; - } catch (NoSuchMethodException exception) { - throw Debug.abort(exception); - } catch (IllegalAccessException exception) { - throw Debug.abort(exception); - } catch (InstantiationException exception) { - throw Debug.abort(exception); - } catch (InvocationTargetException exception) { - throw Debug.abort(exception); - } - } - - /** Returns the object implementing this phase. */ - public Phase phase() { - assert phase != null : "phase " + name + " not yet created"; - return phase; - } - - /** Returns the identifier of this phase. */ - public int id() { - assert id >= 0 : "phase " + name + " not yet frozen"; - return id; - } - - /** Adds the given flag (to previous phase if prev is true). */ - public void addFlag(int flag, boolean prev) { - assert id < 0 : "phase " + name + " already frozen"; - flags |= flag << (prev ? 16 : 0); - } - - /** Adds the SKIP flag. */ - public void addSkipFlag() { - flags |= SKIP; - } - - /** Adds the CHECK flag. */ - public void addCheckFlag() { - flags |= CHECK; - } - - /** Adds the PRINT flag. */ - public void addPrintFlag() { - flags |= PRINT; - } - - /** Adds the GRAPH flag. */ - public void addGraphFlag() { - flags |= GRAPH; - } - - /** Adds the STOP flag. */ - public void addStopFlag() { - flags |= STOP; - } - - /** Adds the LOG flag. */ - public void addLogFlag() { - flags |= LOG; - } - - /** Has this phase the SKIP flag? */ - public boolean hasSkipFlag() { - return (flags & SKIP) != 0; - } - - /** Has this phase the CHECK flag? */ - public boolean hasCheckFlag() { - return (flags & CHECK) != 0; - } - - /** Has this phase the PRINT flag? */ - public boolean hasPrintFlag() { - return (flags & PRINT) != 0; - } - - /** Has this phase the GRAPH flag? */ - public boolean hasGraphFlag() { - return (flags & GRAPH) != 0; - } - - /** Has this phase the STOP flag? */ - public boolean hasStopFlag() { - return (flags & STOP) != 0; - } - - /** Has this phase the LOG flag? */ - public boolean hasLogFlag() { - return (flags & LOG) != 0; - } - - /** Returns the name of this phase. */ - public String toString() { - return name(); - } - - //######################################################################## - // Protected Methods - - /** Initializes this descriptor with given phase. */ - protected void initialize(Phase phase) { - assert phase != null: "illegal null phase"; - assert phase.descriptor == this: phase.descriptor.name + " != " + name; - assert this.phase == null: "phase " + name + " already initialized"; - this.phase = phase; - } - - //######################################################################## -} diff --git a/sources/scalac/Unit.java b/sources/scalac/Unit.java deleted file mode 100644 index 44e131bed7..0000000000 --- a/sources/scalac/Unit.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac; - -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -import scalac.ast.Tree; -import scalac.atree.ARepository; -import scalac.util.FreshNameCreator; -import java.util.HashMap; - - -/** A representation for a compilation unit in scala - * - * @author Matthias Zenger - * @version 1.0 - */ -public class CompilationUnit { - - /** the global compilation environment - */ - public final Global global; - - /** the associated source code file - */ - public final SourceFile source; - - /** does this unit come from the interpreter console - */ - public final boolean console; - - /** is this unit only there for mixin expansion? - */ - public final boolean mixinOnly; - - /** the fresh name creator - */ - public final FreshNameCreator fresh; - - /** the content of the compilation unit in tree form - */ - public Tree[] body; - public ARepository repository; - - public CompilationUnit(Global global, SourceFile source, - boolean console, boolean mixinOnly) { - this.global = global; - this.source = source; - this.console = console; - this.mixinOnly = mixinOnly; - this.fresh = new FreshNameCreator(); - } - - public CompilationUnit(Global global, SourceFile source, boolean console) { - this(global, source, console, false); - } - - /** return the position representing the given encoded position - */ - public Position position(int pos) { - return new Position(source, pos); - } - - /** issue an error in this compilation unit at a specific location - */ - public void error(int pos, String message) { - global.reporter.error(position(pos), message); - } - - /** issue a warning in this compilation unit at a specific location - */ - public void warning(int pos, String message) { - global.reporter.warning(position(pos), message); - } - - /** return a string representation - */ - public String toString() { - return source.toString(); - } - -} diff --git a/sources/scalac/ast/DefaultTreeFactory.java.tmpl b/sources/scalac/ast/DefaultTreeFactory.java.tmpl deleted file mode 100644 index 48fa7760fa..0000000000 --- a/sources/scalac/ast/DefaultTreeFactory.java.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** The default tree factory */ -public class DefaultTreeFactory implements TreeFactory { - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/LazyTreeCopier.java.tmpl b/sources/scalac/ast/LazyTreeCopier.java.tmpl deleted file mode 100644 index 8da7facf2a..0000000000 --- a/sources/scalac/ast/LazyTreeCopier.java.tmpl +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** - * A tree copier that returns a new tree only if some fields have - * changed - */ -public class LazyTreeCopier implements TreeCopier { - - //######################################################################## - // Protected Fields - - /** The tree copier used to copy trees */ - protected final TreeCopier copier; - - //######################################################################## - // Public Constructors - - public LazyTreeCopier(TreeFactory make) { - this(new StrictTreeCopier(make)); - } - - public LazyTreeCopier(TreeCopier copier) { - this.copier = copier; - } - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/StrictTreeCopier.java.tmpl b/sources/scalac/ast/StrictTreeCopier.java.tmpl deleted file mode 100644 index f82653279a..0000000000 --- a/sources/scalac/ast/StrictTreeCopier.java.tmpl +++ /dev/null @@ -1,35 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** A tree copier that returns always a new tree */ -public class StrictTreeCopier implements TreeCopier { - - //######################################################################## - // Protected Fields - - /** The tree factory used to create the tree copies */ - protected final TreeFactory make; - - //######################################################################## - // Public Constructors - - public StrictTreeCopier(TreeFactory make) { - this.make = make; - } - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/Transformer.java.tmpl b/sources/scalac/ast/Transformer.java.tmpl deleted file mode 100644 index 2fa347c305..0000000000 --- a/sources/scalac/ast/Transformer.java.tmpl +++ /dev/null @@ -1,319 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import scalac.Global; -import scalac.CompilationUnit; -import scalac.symtab.Type; -{#Imports#} - -/** - * A default transformer class. This class traverses the abstract - * syntax tree but does not do any transformations. - */ -public class Transformer { - - //######################################################################## - // Public Fields - - /** The global environment */ - public final Global global; - - /** The tree factory */ - public final TreeFactory make; - - /** The tree copier */ - public final TreeCopier copy; - - /** A tree generator */ - public final TreeGen gen; - - //######################################################################## - // Public Constructors - - public Transformer(Global global) { - this(global, global.make); - } - - public Transformer(Global global, TreeFactory make) { - this(global, make, new LazyTreeCopier(make)); - } - - public Transformer(Global global, TreeFactory make, TreeCopier copy) { - this.global = global; - this.make = make; - this.copy = copy; - this.gen = global.treeGen; - } - - //######################################################################## - // Public Methods - - public void apply(CompilationUnit unit) { - unit.global.log("transforming " + unit); - unit.body = transform(unit.body); - } - - public Tree transform(Tree tree) { - {#TreeSwitch#} - } - - public Template transform(Template tree) { - return (Template)transform((Tree)tree); - } - - {#TransformArrays#} - - //######################################################################## -} - - -public class GenTransformer { - - //######################################################################## - // Public Fields - - /** The global environment */ - public final Global global; - - /** The type map */ - public final Type.Map map; - - /** A tree generator */ - public final TreeGen gen; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with an identity type map. */ - public GenTransformer(Global global) { - this(global, Type.IdMap); - } - - /** Initializes this instance with given type map. */ - public GenTransformer(Global global, Type.Map map) { - this.global = global; - this.gen = global.treeGen; - this.map = map; - } - - //######################################################################## - // Public Methods - - /** Transforms the given units. */ - public void apply(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) apply(units[i]); - } - - /** Transforms the given unit. */ - public void apply(CompilationUnit unit) { - unit.global.log("transforming " + unit); - unit.body = transform(unit.body); - } - - /** Transforms the given symbol. */ - public Symbol getSymbolFor(Tree tree) { - return tree.symbol(); - } - - /** Transforms the given types. */ - public Type[] transform(Type[] types) { - for (int i = 0; i < types.length; i++) { - Type type = transform(types[i]); - if (type == types[i]) continue; - Type[] clones = new Type[types.length]; - for (int j = 0; j < i; j++) clones[j] = types[j]; - clones[i] = type; - for (; i < types.length; i++) clones[i] = transform(types[i]); - return clones; - } - return types; - } - - /** Transforms the given type. */ - public Type transform(Type type) { - return map.apply(type); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - - // case Bad(): - - case Empty: - return tree; - - case ClassDef(_, _, _, _, _, Template impl): - Symbol symbol = getSymbolFor(tree); - if (global.currentPhase.id < global.PHASE.ADDCONSTRUCTORS.id()) { - Symbol impl_symbol = getSymbolFor(impl); - Tree[] parents = transform(impl.parents); - Tree[] body = transform(impl.body); - return gen.ClassDef(symbol, parents, impl_symbol, body); - } else { - Tree[] body = transform(impl.body); - return gen.ClassDef(symbol, body); - } - - case PackageDef(Tree packaged, Template(Tree[] parents, Tree[] body)): - Symbol symbol = getSymbolFor(packaged); - assert parents.length == 0: tree; - return gen.PackageDef(symbol, transform(body)); - - // case ModuleDef(_, _, _, Template impl): - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.ValDef(symbol, transform(rhs)); - - // case PatDef(int mods, Tree pat, Tree rhs): - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.DefDef(symbol, transform(rhs)); - - case AbsTypeDef(_, _, _, _): - Symbol symbol = getSymbolFor(tree); - return gen.AbsTypeDef(symbol); - - case AliasTypeDef(_, _, _, _): - Symbol symbol = getSymbolFor(tree); - return gen.AliasTypeDef(symbol); - - case Import(Tree expr, Name[] selectors): - return gen.Import(tree.pos, transform(expr), selectors); - - case CaseDef(Tree pat, Tree guard, Tree body): - pat = transform(pat); - guard = transform(guard); - body = transform(body); - return gen.CaseDef(pat, guard, body); - - // case Template(Tree[] parents, Tree[] body): - - case LabelDef(_, Ident[] params, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.LabelDef(symbol, transform(params), transform(rhs)); - - case Block(Tree[] stats, Tree value): - return gen.Block(tree.pos, transform(stats), transform(value)); - - case Sequence(Tree[] trees): - trees = transform(trees); - Tree seq = new Sequence(trees); - seq.pos = tree.pos; - seq.type = tree.type; - return seq; - // case Alternative(Tree[] trees): - // case Visitor(CaseDef[] cases): - // case Function(ValDef[] vparams, Tree body): - - case Bind(Name n, Tree pat): // test - Symbol sym = getSymbolFor(tree); - global.nextPhase(); - sym.setType(tree.type); - global.prevPhase(); - Tree bind = new ExtBind(sym, transform(pat)); - bind.type = sym.getType(); - bind.pos = tree.pos; - return bind; - - - case Assign(Tree lhs, Tree rhs): - return gen.Assign(tree.pos, transform(lhs), transform(rhs)); - - case If(Tree cond, Tree thenp, Tree elsep): - cond = transform(cond); - thenp = transform(thenp); - elsep = transform(elsep); - if (tree.type().isSameAs(global.definitions.ANY_TYPE())) { - global.nextPhase(); - Type type = global.definitions.ANY_TYPE(); - global.prevPhase(); - return gen.If(tree.pos, cond, thenp, elsep, type); - } else { - return gen.If(tree.pos, cond, thenp, elsep); - } - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - test = transform(test); - bodies = transform(bodies); - otherwise = transform(otherwise); - if (tree.type().isSameAs(global.definitions.ANY_TYPE())) { - global.nextPhase(); - Type type = global.definitions.ANY_TYPE(); - global.prevPhase(); - return gen.Switch(tree.pos, test, tags, bodies,otherwise,type); - } else { - return gen.Switch(tree.pos, test, tags, bodies, otherwise); - } - - case Return(Tree expr): - Symbol symbol = getSymbolFor(tree); - return gen.Return(tree.pos, symbol, transform(expr)); - - // case Throw(Tree expr): - - case New(Tree init): - return gen.New(tree.pos, transform(init)); - - case Create(Tree qualifier, Tree[] args): - Symbol symbol = getSymbolFor(tree); - qualifier = transform(qualifier); - args = transform(args); - return gen.Create(tree.pos, qualifier, symbol, args); - - case Typed(Tree expr, Tree tpe): - return gen.Typed(tree.pos, transform(expr), transform(tpe)); - - case TypeApply(Tree fun, Tree[] args): - return gen.TypeApply(transform(fun), transform(args)); - - case Apply(Tree fun, Tree[] args): - return gen.Apply(transform(fun), transform(args)); - - case Super(_, _): - Symbol symbol = getSymbolFor(tree); - return gen.Super(tree.pos, symbol); - - case This(_): - Symbol symbol = getSymbolFor(tree); - return gen.This(tree.pos, symbol); - - case Select(Tree qualifier, _): - Symbol symbol = getSymbolFor(tree); - return gen.Select(tree.pos, transform(qualifier), symbol); - - case Ident(_): - Symbol symbol = getSymbolFor(tree); - return gen.Ident(tree.pos, symbol); - - case Literal(AConstant value): - return gen.Literal(tree.pos, value); - - case TypeTerm(): - return gen.mkType(tree.pos, transform(tree.type())); - - // case SingletonType(Tree ref): - // case SelectFromType(Tree qualifier, Name selector): - // case FunType(Tree[] argtpes, Tree restpe): - // case CompoundType(Tree[] parents, Tree[] refinements): - // case AppliedType(Tree tpe, Tree[] args): - // case Try(Tree block, Tree catcher, Tree finalizer): - - default: - throw Debug.abort("illegal case", tree); - } - } - - {#TransformArrays#} - - //######################################################################## -} diff --git a/sources/scalac/ast/Traverser.java.tmpl b/sources/scalac/ast/Traverser.java.tmpl deleted file mode 100644 index a17768e2b4..0000000000 --- a/sources/scalac/ast/Traverser.java.tmpl +++ /dev/null @@ -1,35 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import scalac.CompilationUnit; -{#Imports#} - -/** Class to traverse a tree without modifying it. */ -public class Traverser { - - //######################################################################## - // Public Methods - - public void traverse(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) traverse(units[i]); - } - - public void traverse(CompilationUnit unit) { - traverse(unit.body); - } - - public void traverse(Tree tree) { - {#TreeSwitch#} - } - - {#TraverseArrays#} - - //######################################################################## -} diff --git a/sources/scalac/ast/Tree.java.tmpl b/sources/scalac/ast/Tree.java.tmpl deleted file mode 100644 index c76c2b37d0..0000000000 --- a/sources/scalac/ast/Tree.java.tmpl +++ /dev/null @@ -1,202 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import java.io.PrintWriter; -import java.io.StringWriter; - -import scala.tools.util.Position; - -import scalac.Global; -import scalac.ast.printer.TreePrinter; -import scalac.checkers.CheckTreeNodes; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Names; -{#Imports#} - -public class Tree { - - //######################################################################## - // Public Constants - - {#EmptyArrays#} - - //######################################################################## - // Public Fields - - /** The position of the tree */ - public int pos = Position.NOPOS; - - /** The type of the tree */ - public Type type; - - //######################################################################## - // Public Cases - - {#TreeCases#} - - //######################################################################## - // Public Methods - queries - - {#IsKind#} - - //######################################################################## - // Public Methods - tree type - - /** Get the type of the node. */ - public final Type getType() { - return type; - } - - /** Get the type of the node, which must be non-null. */ - public Type type() { - assert type != null : Debug.show(this); - return type; - } - - /** Set the type of the node. */ - public Tree setType(Type type) { - assert !(type instanceof Type.LazyType) : Debug.show(this); - this.type = type; - return this; - } - - /** Get types attached to array of nodes. */ - public static Type[] typeOf(Tree[] trees) { - Type[] types = new Type[trees.length]; - for (int i = 0; i < trees.length; i++) types[i] = trees[i].getType(); - return types; - } - - //######################################################################## - // Public Methods - tree symbol - - /** Has this tree a symbol field? */ - public boolean hasSymbol() { - return false; - } - - /** Tells if the tree defines a symbol. */ - public boolean definesSymbol() { - return false; - } - - /** Get symbol attached to the node, if any. */ - public Symbol symbol() { - return null; - } - - /** Set symbol attached to the node, if possible. */ - public Tree setSymbol(Symbol sym) { - throw Debug.abort("no settable symbol for node", this); - } - - /** Get symbols attached to array of nodes. */ - public static Symbol[] symbolOf(Tree[] trees) { - Symbol[] symbols = new Symbol[trees.length]; - for (int i = 0; i < trees.length; i++) symbols[i] = trees[i].symbol(); - return symbols; - } - - //######################################################################## - // Public Methods - tree to string - - /** Returns the string representation of this tree. */ - public String toString() { - StringWriter buffer = new StringWriter(); - TreePrinter printer = - Global.instance.newTextTreePrinter(new PrintWriter(buffer)); - printer.print(this); - printer.flush(); - return buffer.toString(); - } - - //######################################################################## - // Public Methods - duplication - - public static Transformer duplicator; - - /** Returns a shallow copy of the given array. */ - public static Tree[] cloneArray(Tree[] array) { - return cloneArray(0, array, 0); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items. - */ - public static Tree[] cloneArray(int prefix, Tree[] array) { - return cloneArray(prefix, array, 0); - } - - /** - * Returns a shallow copy of the given array suffixed by "suffix" - * null items. - */ - public static Tree[] cloneArray(Tree[] array, int suffix) { - return cloneArray(0, array, suffix); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items and suffixed by "suffix" null items. - */ - public static Tree[] cloneArray(int prefix, Tree[] array, int suffix) { - assert prefix >= 0 && suffix >= 0: prefix + " - " + suffix; - int size = prefix + array.length + suffix; - if (size == 0) return EMPTY_ARRAY; - Tree[] clone = new Tree[size]; - for (int i = 0; i < array.length; i++) clone[prefix + i] = array[i]; - return clone; - } - - /** Returns the concatenation of the two arrays. */ - public static Tree[] concat(Tree[] array1, Tree[] array2) { - if (array1.length == 0) return array2; - if (array2.length == 0) return array1; - Tree[] clone = cloneArray(array1.length, array2); - for (int i = 0; i < array1.length; i++) clone[i] = array1[i]; - return clone; - } - - public Tree duplicate() { - if (duplicator == null) duplicator =new Transformer( - Global.instance, Global.instance.make, - new StrictTreeCopier(Global.instance.make)); - return duplicator.transform(this); - } - - //######################################################################## - // Public Classes - - {#ExtClasses#} - - //######################################################################## - // Empty Switch - - /* - - public void foobar(Tree tree) { - - switch (tree) { - - {#EmptyCases#} - - default: - throw Debug.abort("illegal case", tree); - } - - } - - */ - - //######################################################################## -} diff --git a/sources/scalac/ast/TreeCloner.java b/sources/scalac/ast/TreeCloner.java deleted file mode 100644 index 8d96c1b23e..0000000000 --- a/sources/scalac/ast/TreeCloner.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import java.util.Map; - -import scalac.Global; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolCloner; -import scalac.symtab.SymbolSubstTypeMap; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This class implements a deep tree cloner. It provides support to - * change tree symbols and tree types on the fly. This cloner never - * clones symbols, but its default implementation of getSymbolFor - * requires that all symbols that are defined by the tree to be cloned - * are present in the symbol substitution. This implies that if the - * tree to clone contains definitions, it must first be traversed to - * map all defined symbols. To do this, one can use TreeSymbolCloner. - */ -public class TreeCloner extends Transformer { - - //######################################################################## - // Private Fields - - /** The symbol substitution to apply to tree symbols */ - private final Map/*<Symbol,Symbol>*/ symbols; - - /** The type map to apply to tree types */ - private final Type.Map types; - - //######################################################################## - // Public Constructors - - /** Initializes a new instance. */ - public TreeCloner(Global global, SymbolSubstTypeMap types) { - this(global, types.getSymbols(), types); - } - - /** Initializes a new instance. */ - public TreeCloner(Global global, Map symbols, Type.Map types) { - super(global, global.make, new StrictTreeCopier(global.make)); - this.symbols = symbols; - this.types = types; - } - - //######################################################################## - // Public Methods - - /** - * Returns the symbol for the given cloned tree. The default - * implementation returns the result of the application of the - * symbol substitution to the given tree's symbol. If there is no - * mapping for that symbol returns that same symbol. - */ - public Symbol getSymbolFor(Tree tree) { - Symbol oldsym = tree.symbol(); - Symbol newsym = (Symbol)symbols.get(oldsym); - // cloned definitions must have a cloned symbol - assert newsym != null || !tree.definesSymbol() : Debug.show(oldsym); - return newsym != null ? newsym : oldsym; - } - - /** - * Returns the type for the given cloned tree. The default - * implementation returns the result of the application of the - * type map to the given tree's type. - */ - public Type getTypeFor(Tree tree) { - return types.apply(tree.getType()); - } - - /** Traverses the given tree and returns a deeply cloned one. */ - public Tree transform(Tree tree) { - tree = super.transform(tree); - if (tree.hasSymbol()) tree.setSymbol(getSymbolFor(tree)); - tree.setType(getTypeFor(tree)); - return tree; - } - - //######################################################################## -} - - -/** !!! */ -public class GenTreeCloner extends GenTransformer { - - //######################################################################## - // Public Fields - - /** The symbol cloner */ - public final SymbolCloner cloner; - - //######################################################################## - // Public Constructors - - /** Initializes a new instance. */ - public GenTreeCloner(Global global, Type.Map map, SymbolCloner cloner) { - super(global, map); - this.cloner = cloner; - } - - public GenTreeCloner(Global global, SymbolCloner cloner) { - super(global, cloner.getTypeMap()); - this.cloner = cloner; - } - - //######################################################################## - // Public Methods - - public Symbol getSymbolFor(Tree tree) { - switch (tree) { - case ValDef(_, _, _, _): - if (tree.symbol().owner().isClass()) break; - Symbol symbol = cloner.cloneSymbol(tree.symbol()); - symbol.setType(transform(symbol.type())); - return symbol; - case LabelDef(_, _, _): - Symbol symbol = cloner.cloneSymbol(tree.symbol()); - symbol.setType(transform(symbol.type())); - return symbol; - } - Symbol symbol = (Symbol)cloner.clones.get(tree.symbol()); - assert !tree.definesSymbol() || symbol != null: tree; - return symbol != null ? symbol : tree.symbol(); - } - - //######################################################################## -} diff --git a/sources/scalac/ast/TreeCopier.java.tmpl b/sources/scalac/ast/TreeCopier.java.tmpl deleted file mode 100644 index 27a9cf476e..0000000000 --- a/sources/scalac/ast/TreeCopier.java.tmpl +++ /dev/null @@ -1,26 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** - * Interface for a kind of factory which, for each node constructor, - * takes an original node from which some data will be copied or - * shared. - */ -public interface TreeCopier { - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/TreeFactory.java.tmpl b/sources/scalac/ast/TreeFactory.java.tmpl deleted file mode 100644 index 3b46970e77..0000000000 --- a/sources/scalac/ast/TreeFactory.java.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** This interface describes a tree factory */ -public interface TreeFactory { - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java deleted file mode 100644 index 49e97c24d7..0000000000 --- a/sources/scalac/ast/TreeGen.java +++ /dev/null @@ -1,1361 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import scalac.Global; -import scalac.ast.Tree.*; -import scalac.atree.AConstant; -import scalac.symtab.*; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.TypeNames; - -/** - * This class provides method to build attributed trees. - * - * @author Martin Odersky, Christine Roeckl - * @version 1.0 - */ -public class TreeGen implements Kinds, Modifiers, TypeTags { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The global definitions */ - private final Definitions definitions; - - /** The tree factory */ - private final TreeFactory make; - - /** Initializes this instance. */ - public TreeGen(Global global) { - this(global, global.make); - } - - /** Initializes this instance. */ - public TreeGen(Global global, TreeFactory make) { - this.global = global; - this.definitions = global.definitions; - this.make = make; - } - - //######################################################################## - // Public Methods - Building types - - /** Builds type references corresponding to given symbols. */ - public Tree[] mkTypeRefs(int pos, Symbol[] syms) { - if (syms.length == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[syms.length]; - for (int i = 0; i < trees.length; i++) - trees[i] = mkTypeRef(pos, syms[i]); - return trees; - } - - /** Builds a type reference corresponding to given symbol. */ - public Tree mkTypeRef(int pos, Symbol sym) { - assert sym.kind == TYPE: Debug.show(sym); - sym.flags |= ACCESSED; - return mkType(pos, sym.nextType()); - } - - /** Builds trees corresponding to given types. */ - public Tree[] mkTypes(int pos, Type[] types) { - if (types.length == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[types.length]; - for (int i = 0; i < trees.length; i++) - trees[i] = mkType(pos, types[i]); - return trees; - } - - /** Builds a tree corresponding to given type. */ - public Tree mkType(int pos, Type type) { - return TypeTerm(pos, type); - } - - /** Builds a TypeTerm node corresponding to given type. */ - public TypeTerm TypeTerm(int pos, Type type) { - TypeTerm tree = make.TypeTerm(pos); - tree.setType(type); - return tree; - } - - //######################################################################## - // Public Methods - Building constants - - /** Builds a unit literal. */ - public Tree mkUnitLit(int pos) { - return Literal(pos, AConstant.UNIT); - } - - /** Builds a boolean literal. */ - public Tree mkBooleanLit(int pos, boolean value) { - return Literal(pos, AConstant.BOOLEAN(value)); - } - - /** Builds a byte literal. */ - public Tree mkByteLit(int pos, byte value) { - return Literal(pos, AConstant.BYTE(value)); - } - - /** Builds a short literal. */ - public Tree mkShortLit(int pos, short value) { - return Literal(pos, AConstant.SHORT(value)); - } - - /** Builds a character literal. */ - public Tree mkCharLit(int pos, char value) { - return Literal(pos, AConstant.CHAR(value)); - } - - /** Builds an integer literal */ - public Tree mkIntLit(int pos, int value) { - return Literal(pos, AConstant.INT(value)); - } - - /** Builds a long literal. */ - public Tree mkLongLit(int pos, long value) { - return Literal(pos, AConstant.LONG(value)); - } - - /** Builds a float literal. */ - public Tree mkFloatLit(int pos, float value) { - return Literal(pos, AConstant.FLOAT(value)); - } - - /** Builds a double literal. */ - public Tree mkDoubleLit(int pos, double value) { - return Literal(pos, AConstant.DOUBLE(value)); - } - - /** Builds a string literal. */ - public Tree mkStringLit(int pos, String value) { - assert value != null; - return Literal(pos, AConstant.STRING(value)); - } - - /** Builds a symbol name literal. */ - public Tree mkSymbolNameLit(int pos, Symbol value) { - return Literal(pos, AConstant.SYMBOL_NAME(value)); - } - - /** Builds a null literal. */ - public Tree mkNullLit(int pos) { - return Literal(pos, AConstant.NULL); - } - - /** Builds a zero literal. */ - public Tree mkZeroLit(int pos) { - return Literal(pos, AConstant.ZERO); - } - - /** Builds a default zero value according to given type tag. */ - public Tree mkDefaultValue(int pos, int tag) { - switch (tag) { - case UNIT : return mkUnitLit(pos); - case BOOLEAN: return mkBooleanLit(pos, false); - case BYTE : return mkByteLit(pos, (byte)0); - case SHORT : return mkShortLit(pos, (short)0); - case CHAR : return mkCharLit(pos, '\0'); - case INT : return mkIntLit(pos, 0); - case LONG : return mkLongLit(pos, 0l); - case FLOAT : return mkFloatLit(pos, 0f); - case DOUBLE : return mkDoubleLit(pos, 0d); - default : throw Debug.abort("unknown type tag: " + tag); - } - } - - /** Builds a default zero value according to given type. */ - public Tree mkDefaultValue(int pos, Type type) { - switch (type.unbox()) { - case UnboxedType(int tag): return mkDefaultValue(pos, tag); - } - if (definitions.ALLREF_TYPE().isSubType(type)) return mkNullLit(pos); - return mkZeroLit(pos); - } - - /** Builds a Literal node of given value. */ - public Literal Literal(int pos, AConstant value) { - Literal tree = make.Literal(pos, value); - global.nextPhase(); - tree.setType(definitions.atyper.type(value)); - global.prevPhase(); - return tree; - } - - //######################################################################## - // Public Methods - Building references - - /** - * Builds a reference to primary constructor of given class with - * given qualifier. - */ - public Tree mkPrimaryConstructorRef(int pos, Tree qualifier, Symbol clasz){ - return mkRef(pos, qualifier, primaryConstructorOf(clasz)); - } - public Tree mkPrimaryConstructorRef(Tree qualifier, Symbol clasz) { - return mkPrimaryConstructorRef(qualifier.pos, qualifier, clasz); - } - - /** - * Builds a reference to primary constructor of given class with - * given stable prefix. - */ - public Tree mkPrimaryConstructorRef(int pos, Type stable, Symbol clasz) { - return mkRef(pos, stable, primaryConstructorOf(clasz)); - } - - /** - * Builds a local reference to primary constructor of given class. - */ - public Tree mkPrimaryConstructorLocalRef(int pos, Symbol clasz) { - return mkLocalRef(pos, primaryConstructorOf(clasz)); - } - - /** - * Builds a global reference to primary constructor of given - * class. - */ - public Tree mkPrimaryConstructorGlobalRef(int pos, Symbol clasz) { - return mkGlobalRef(pos, primaryConstructorOf(clasz)); - } - - /** Builds local references to given symbols. */ - public Tree[] mkLocalRefs(int pos, Symbol[] symbols) { - if (symbols.length == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[symbols.length]; - for (int i = 0; i < trees.length; i++) - trees[i] = mkLocalRef(pos, symbols[i]); - return trees; - } - - /** Builds global references to given symbols. */ - public Tree[] mkGlobalRefs(int pos, Symbol[] symbols) { - if (symbols.length == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[symbols.length]; - for (int i = 0; i < trees.length; i++) - trees[i] = mkGlobalRef(pos, symbols[i]); - return trees; - } - - /** Builds a reference to given symbol with given qualifier. */ - public Tree mkRef(int pos, Tree qualifier, Symbol symbol) { - return Select(pos, qualifier, symbol); - } - public Tree mkRef(Tree qualifier, Symbol symbol) { - return mkRef(qualifier.pos, qualifier, symbol); - } - - /** - * Builds a reference to given symbol with given stable prefix. - */ - public Tree mkRef(int pos, Type stable, Symbol symbol) { - Tree qualifier = mkQualifier(pos, stable); - if (qualifier == Tree.Empty) return Ident(pos, symbol); - return mkRef(pos, qualifier, symbol); - } - - /** Builds a local reference to given symbol. */ - public Tree mkLocalRef(int pos, Symbol symbol) { - assert symbol.isTerm(): Debug.show(symbol); - Type prefix = symbol.hasStaticAttribute() - ? Type.NoPrefix - : symbol.owner().thisType(); - return mkRef(pos, prefix, symbol); - } - - /** Builds a global reference to given symbol. */ - public Tree mkGlobalRef(int pos, Symbol symbol) { - assert symbol.isTerm(): Debug.show(symbol); - global.nextPhase(); - Type prefix = symbol.owner().staticPrefix(); - global.prevPhase(); - return mkRef(pos, prefix, symbol); - } - - /** Builds a qualifier corresponding to given stable prefix. */ - public Tree mkQualifier(int pos, Type stable) { - switch (stable) { - case NoPrefix: - return Tree.Empty; - case ThisType(Symbol clasz): - return This(pos, clasz); - case SingleType(Type prefix, Symbol member): - Tree qualifier = mkRef(pos, prefix, member); - switch (qualifier.type()) { - case MethodType(Symbol[] params, _): - assert params.length == 0: qualifier.type(); - return Apply(pos, qualifier); - default: - return qualifier; - } - default: - throw Debug.abort("illegal case", stable); - } - } - - /** Builds a This node corresponding to given class. */ - public This This(int pos, Symbol clazz) { - assert clazz.isClassType(): Debug.show(clazz); - This tree = make.This(pos, clazz); - global.nextPhase(); - tree.setType(clazz.thisType()); - global.prevPhase(); - return tree; - } - - /** Builds a Super node corresponding to given class. */ - public Super Super(int pos, Symbol clazz) { - assert clazz.isClass(): Debug.show(clazz); - Super tree = make.Super(pos, clazz, TypeNames.EMPTY); - global.nextPhase(); - tree.setType(clazz.thisType()); - global.prevPhase(); - return tree; - } - - /** Builds an Ident node corresponding to given symbol. */ - public Ident Ident(int pos, Symbol sym) { - assert sym.isTerm(): Debug.show(sym); - sym.flags |= ACCESSED; - Ident tree = make.Ident(pos, sym); - global.nextPhase(); - Type type; - if (sym.isInitializer()) { - type = sym.type(); - Symbol[] tparams = sym.owner().typeParams(); - if (tparams.length != 0) type = Type.PolyType(tparams, type); - } else { - type = sym.owner().thisType().memberStabilizedType(sym); - } - tree.setType(type); - global.prevPhase(); - return tree; - } - - /** - * Builds a Select node corresponding to given symbol selected - * from given qualifier. - */ - public Select Select(int pos, Tree qualifier, Symbol sym) { - assert sym.isTerm(): Debug.show(sym); - sym.flags |= ACCESSED | SELECTOR; - Select tree = make.Select(pos, sym, qualifier); - global.nextPhase(); - tree.setType(qualifier.type.memberStabilizedType(sym)); - global.prevPhase(); - return tree; - } - public Select Select(Tree qualifier, Symbol sym) { - return Select(qualifier.pos, qualifier, sym); - } - - //######################################################################## - // Public Methods - Building applications - - /** - * Builds an application with given function, type arguments and - * value arguments. - */ - public Tree mkApplyTV(int pos, Tree fn, Type[] targs, Tree[] vargs) { - if (targs.length != 0) fn = TypeApply(pos, fn, mkTypes(pos, targs)); - if (vargs.length == 0 && fn.getType().isObjectType()) return fn; - else return Apply(pos, fn, vargs); - } - public Tree mkApplyTV(Tree fn, Type[] targs, Tree[] vargs) { - return mkApplyTV(fn.pos, fn, targs, vargs); - } - public Tree mkApplyTV(int pos, Tree fn, Tree[] targs, Tree[] vargs) { - if (targs.length != 0) fn = TypeApply(pos, fn, targs); - if (vargs.length == 0 && fn.getType().isObjectType()) return fn; - else return Apply(pos, fn, vargs); - } - public Tree mkApplyTV(Tree fn, Tree[] targs, Tree[] vargs) { - return mkApplyTV(fn.pos, fn, targs, vargs); - } - - /** - * Builds an application with given function and type arguments - * and with no value arguments. - */ - public Tree mkApplyT_(int pos, Tree fn, Type[] targs) { - return mkApplyTV(pos, fn, targs, Tree.EMPTY_ARRAY); - } - public Tree mkApplyT_(Tree fn, Type[] targs) { - return mkApplyT_(fn.pos, fn, targs); - } - public Tree mkApplyT_(int pos, Tree fn, Tree[] targs) { - return mkApplyTV(pos, fn, targs, Tree.EMPTY_ARRAY); - } - public Tree mkApplyT_(Tree fn, Tree[] targs) { - return mkApplyT_(fn.pos, fn, targs); - } - - /** - * Builds an application with given function, no type arguments - * and given value arguments. - */ - public Tree mkApply_V(int pos, Tree fn, Tree[] vargs) { - return mkApplyTV(pos, fn, Tree.EMPTY_ARRAY, vargs); - } - public Tree mkApply_V(Tree fn, Tree[] vargs) { - return mkApply_V(fn.pos, fn, vargs); - } - - /** - * Builds an application with given function and no type arguments - * and no value arguments. - */ - public Tree mkApply__(int pos, Tree fn) { - return mkApplyTV(pos, fn, Tree.EMPTY_ARRAY, Tree.EMPTY_ARRAY); - } - public Tree mkApply__(Tree fn) { - return mkApply__(fn.pos, fn); - } - - /** Builds a TypeApply node with given function and arguments. */ - public TypeApply TypeApply(int pos, Tree fn, Type[] targs) { - return TypeApply(pos, fn, mkTypes(pos, targs)); - } - public TypeApply TypeApply(Tree fn, Type[] targs) { - return TypeApply(fn.pos, fn, targs); - } - public TypeApply TypeApply(int pos, Tree fn, Tree[] targs) { - Type fnType = fn.type(); - switch (fnType) { - case Type.OverloadedType(_, _): - // TreeGen only builds trees, names must already be resolved - throw Debug.abort("unresolved name", fn + " - " + fnType); - case Type.PolyType(Symbol[] tparams, Type restpe): - global.nextPhase(); - restpe = restpe.subst(tparams, Tree.typeOf(targs)); - global.prevPhase(); - return (TypeApply)make.TypeApply(pos, fn, targs).setType(restpe); - default: - throw Debug.abort("illegal case", fn + " - " + fnType + " - " + fnType.getClass()); - } - } - public TypeApply TypeApply(Tree fn, Tree[] targs) { - return TypeApply(fn.pos, fn, targs); - } - - /** Builds an Apply node with given function and arguments. */ - public Apply Apply(int pos, Tree fn, Tree[] vargs) { - Type fnType = fn.type(); - switch (fnType) { - case Type.OverloadedType(_, _): - // TreeGen only builds trees, names must already be resolved - throw Debug.abort("unresolved name", fn + " - " + fnType); - case Type.MethodType(Symbol[] vparams, Type restpe): - return (Apply)make.Apply(pos, fn, vargs).setType(restpe); - default: - throw Debug.abort("illegal case", fn + " - " + fnType + " - " + fnType.getClass()); - } - } - public Apply Apply(Tree fn, Tree[] vargs) { - return Apply(fn.pos, fn, vargs); - } - - /** Builds an Apply node with given function and no arguments. */ - public Apply Apply(int pos, Tree fn) { - return Apply(pos, fn, Tree.EMPTY_ARRAY); - } - public Apply Apply(Tree fn) { - return Apply(fn.pos, fn); - } - - //######################################################################## - // Public Methods - Building new instances - - /** - * Builds a new instance creation with given qualifier, - * initializer, type arguments and value arguments. - */ - public Tree mkNewTV(int pos, Tree qual, Symbol init, Type[] targs, - Tree[] vargs) - { - return mkNewTV(pos, qual, init, mkTypes(pos, targs), vargs); - } - public Tree mkNewTV(Tree qual, Symbol init, Type[] targs, Tree[] vargs) { - return mkNewTV(qual.pos, qual, init, targs, vargs); - } - public Tree mkNewTV(int pos, Tree qual, Symbol init, Tree[] targs, - Tree[] vargs) - { - assert init.isInitializer(): Debug.show(init); - Tree instance = Create(pos, qual, init.owner(), targs); - return New(pos, Apply(pos, Select(pos, instance, init), vargs)); - } - public Tree mkNewTV(Tree qual, Symbol init, Tree[] targs, Tree[] vargs) { - return mkNewTV(qual.pos, qual, init, targs, vargs); - } - - /** - * Builds a new instance creation with given qualifier, - * initializer and type arguments and no value arguments. - */ - public Tree mkNewT_(int pos, Tree qual, Symbol init, Type[] targs) { - return mkNewTV(pos, qual, init, targs, Tree.EMPTY_ARRAY); - } - public Tree mkNewT_(Tree qual, Symbol init, Type[] targs) { - return mkNewT_(qual.pos, qual, init, targs); - } - public Tree mkNewT_(int pos, Tree qual, Symbol init, Tree[] targs) { - return mkNewTV(pos, qual, init, targs, Tree.EMPTY_ARRAY); - } - public Tree mkNewT_(Tree qual, Symbol init, Tree[] targs) { - return mkNewT_(qual.pos, qual, init, targs); - } - - /** - * Builds a new instance creation with given qualifier, - * initializer and value arguments and no type arguments. - */ - public Tree mkNew_V(int pos, Tree qual, Symbol init, Tree[] vargs) { - return mkNewTV(pos, qual, init, Tree.EMPTY_ARRAY, vargs); - } - public Tree mkNew_V(Tree qual, Symbol init, Tree[] vargs) { - return mkNew_V(qual.pos, qual, init, vargs); - } - - /** - * Builds a new instance creation with given qualifier, and - * initializer and no type arguments and no value arguments. - */ - public Tree mkNew__(int pos, Tree qual, Symbol init) { - return mkNewTV(pos, qual, init, Tree.EMPTY_ARRAY, Tree.EMPTY_ARRAY); - } - public Tree mkNew__(Tree qual, Symbol init) { - return mkNew__(qual.pos, qual, init); - } - - /** Builds a New node corresponding to "new <init>". */ - public New New(int pos, Tree init) { - New tree = make.New(pos, init); - tree.setType(init.type()); - // after AddConstructor use type of Create node - switch (init) { - case Apply(Select(Tree qual, _), _): - if (qual instanceof Tree.Create) tree.setType(qual.type()); - } - return tree; - } - public New New(Tree init) { - return New(init.pos, init); - } - - /** - * Builds a Create node with given qualifier, clasz and type - * arguments. - */ - public Create Create(int pos, Tree qual, Symbol clasz, Type[] targs) { - return Create(pos, qual, clasz, mkTypes(pos, targs)); - } - public Create Create(Tree qual, Symbol clasz, Type[] targs) { - return Create(qual.pos, qual, clasz, targs); - } - public Create Create(int pos, Tree qual, Symbol clasz, Tree[] targs) { - assert clasz.isClass(): Debug.show(clasz); - Create tree = make.Create(pos, clasz, qual, targs); - global.nextPhase(); - assert targs.length == clasz.typeParams().length: tree; - Type prefix = qual == Tree.Empty ? Type.NoPrefix:qual.type(); - tree.setType(Type.typeRef(prefix, clasz, Tree.typeOf(targs))); - global.prevPhase(); - return tree; - } - public Create Create(Tree qual, Symbol clasz, Tree[] targs) { - return Create(qual.pos, qual, clasz, targs); - } - - /** - * Builds a Create node with given qualifier, clasz and no type - * arguments. - */ - public Create Create(int pos, Tree qual, Symbol clasz) { - return Create(pos, qual, clasz, Tree.EMPTY_ARRAY); - } - public Create Create(Tree qual, Symbol clasz) { - return Create(qual.pos, qual, clasz); - } - - /** Builds a Create node with given type. */ - public Create Create(int pos, Type type) { - switch (type) { - case TypeRef(Type prefix, Symbol clasz, Type[] targs): - return Create(pos, mkQualifier(pos, prefix), clasz, targs); - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## - // Public Methods - Building expressions - Simple nodes - - /** Flattens the given tree array by inlining Block nodes. */ - public Tree[] flatten_(Tree[] trees) { - boolean copy = false; - int length = 0; - for (int i = 0; i < trees.length; i++) { - switch (trees[i]) { - case Empty: - copy = true; - length -= 1; - continue; - case Block(Tree[] stats, Tree value): - copy = true; - length += stats.length + 1; - continue; - } - length += 1; - } - if (!copy) return trees; - Tree[] clone = new Tree[length]; - for (int i = 0, o = 0; i < trees.length; i++) { - switch (trees[i]) { - case Empty: - continue; - case Block(Tree[] stats, Tree value): - for (int j = 0; j < stats.length; j++) clone[o++] = stats[j]; - clone[o++] = value; - continue; - } - clone[o++] = trees[i]; - } - return clone; - } - - /** Builds an import of all names of given qualifier. */ - public Import mkImportAll(int pos, Tree qualifier) { - return Import(pos, qualifier, new Name[]{Names.IMPORT_WILDCARD}); - } - public Import mkImportAll(Tree qualifier) { - return mkImportAll(qualifier.pos, qualifier); - } - public Import mkImportAll(int pos, Symbol qualifier) { - return mkImportAll(pos, mkGlobalRef(pos, qualifier)); - } - - /** Builds an instance test with given value and type. */ - public Tree mkIsInstanceOf(int pos, Tree value, Type type, boolean erased) { - Symbol sym = erased ? definitions.ANY_IS_ERASED : definitions.ANY_IS; - return mkApplyT_(pos, Select(value, sym), new Type[]{type}); - } - public Tree mkIsInstanceOf(int pos, Tree value, Type type) { - boolean afterTAV = - global.currentPhase.id >= global.PHASE.TYPESASVALUES.id(); - return mkIsInstanceOf(pos, value, type, afterTAV); - } - public Tree mkIsInstanceOf(Tree value, Type type) { - return mkIsInstanceOf(value.pos, value, type); - } - - /** Builds a cast with given value and type. */ - public Tree mkAsInstanceOf(int pos, Tree value, Type type, boolean erased) { - Symbol sym = erased ? definitions.ANY_AS_ERASED : definitions.ANY_AS; - return mkApplyT_(pos, Select(value, sym), new Type[]{type}); - } - public Tree mkAsInstanceOf(int pos, Tree value, Type type) { - boolean afterTAV = - global.currentPhase.id >= global.PHASE.TYPESASVALUES.id(); - return mkAsInstanceOf(pos, value, type, afterTAV); - } - public Tree mkAsInstanceOf(Tree value, Type type) { - return mkAsInstanceOf(value.pos, value, type); - } - - /** Builds an expression of type Unit with given statements. */ - public Tree mkUnitBlock(int pos, Tree[] stats) { - return mkBlock(pos, stats, mkUnitLit(pos)); - } - - /** Builds an expression of type Unit with given statement. */ - public Tree mkUnitBlock(int pos, Tree stat) { - return mkUnitBlock(pos, new Tree[]{stat}); - } - public Tree mkUnitBlock(Tree stat) { - return mkUnitBlock(stat.pos, stat); - } - - /** Builds an expression with given statements and value. */ - public Tree mkBlock(int pos, Tree[] stats, Tree value) { - if (stats.length == 0) return value; - return Block(pos, stats, value); // !!! add flatten? - } - public Tree mkBlock(Tree[] stats, Tree value) { - return mkBlock((stats.length!=0 ? stats[0] : value).pos, stats, value); - } - - /** Builds an expression with given statement and value. */ - public Tree mkBlock(int pos, Tree stat, Tree value) { - switch (stat) { - case Empty: - return value; - case Block(Tree[] block_stats, Tree block_value): - Tree[] stats = Tree.cloneArray(block_stats, 1); - stats[block_stats.length] = block_value; - return Block(stat.pos, stats, value); - default: - return Block(pos, new Tree[]{stat}, value); - } - } - public Tree mkBlock(Tree stat, Tree value) { - return mkBlock(stat.pos, stat, value); - } - - /** Builds an Import node with given qualifier and names. */ - public Import Import(int pos, Tree qualifier, Name[] names) { - Import tree = make.Import(pos, qualifier.symbol(), qualifier, names); - tree.setType(Type.NoType); - return tree; - } - public Import Import(Tree qualifier, Name[] names) { - return Import(qualifier.pos, qualifier, names); - } - public Import Import(int pos, Symbol qualifier, Name[] names) { - return Import(pos, mkGlobalRef(pos, qualifier), names); - } - - /** Builds a Template node with given symbol, parents and body. */ - public Template Template(int pos, Symbol local, Tree[]parents, Tree[]body){ - Template tree = make.Template(pos, local, parents, body); - tree.setType(Type.NoType); - return tree; - } - - /** Builds a Block node with given statements and value. */ - public Block Block(int pos, Tree[] stats, Tree value) { - inline: - switch (value) { - case Block(Tree[] value_stats, Tree value_value): - int count = 0; - for (int i = 0; i < value_stats.length; i++) { - if (value_stats[i].definesSymbol()) break inline; - if (value_stats[i] != Tree.Empty) count++; - } - Tree[] array = Tree.cloneArray(stats, count); - for (int i = 0, j = stats.length; i < value_stats.length; i++) { - if (value_stats[i] != Tree.Empty) array[j++] = value_stats[i]; - } - stats = array; - value = value_value; - } - Block tree = make.Block(pos, stats, value); - tree.setType(value.type()); - return tree; - } - public Block Block(Tree[] stats, Tree value) { - return Block((stats.length != 0 ? stats[0] : value).pos, stats, value); - } - - /** Builds an Assign node corresponding to "<lhs> = <rhs>". */ - public Assign Assign(int pos, Tree lhs, Tree rhs) { - Assign tree = make.Assign(pos, lhs, rhs); - global.nextPhase(); - tree.setType(definitions.void_TYPE()); - global.prevPhase(); - return tree; - } - public Assign Assign(Tree lhs, Tree rhs) { - return Assign(lhs.pos, lhs, rhs); - } - - /** Builds an If node with given components and type. */ - public If If(int pos, Tree cond, Tree thenpart, Tree elsepart, Type type) { - //if (!thenpart.type.isSubType(type)) System.out.println(type + "!>:(" + thenpart.type + "," + elsepart.type + ")");//debug - assert assertTreeSubTypeOf(thenpart, type); - assert assertTreeSubTypeOf(elsepart, type); - If tree = make.If(pos, cond, thenpart, elsepart); - tree.setType(type); - return tree; - } - public If If(Tree cond, Tree thenpart, Tree elsepart, Type type) { - return If(cond.pos, cond, thenpart, elsepart, type); - } - - /** Builds an If node with given condition and branches. */ - public If If(int pos, Tree cond, Tree thenpart, Tree elsepart) { - global.nextPhase(); - Type type = thenpart.getType().isSameAs(elsepart.getType()) - ? thenpart.type - : Type.lub(new Type[] {thenpart.getType(), elsepart.getType()}); - global.prevPhase(); - return If(pos, cond, thenpart, elsepart, type); - } - public If If(Tree cond, Tree thenpart, Tree elsepart) { - return If(cond.pos, cond, thenpart, elsepart); - } - - /** Builds a Switch node with given components and type. - * @param tags a <b>sorted</b> array of tags - */ - public Switch Switch(int pos, Tree test, int[] tags, Tree[] bodies, - Tree otherwise, Type type) - { - for (int i = 0; i < bodies.length; i++) { - assert assertTreeSubTypeOf(bodies[i], type); - assert (i==0) || ( tags[i-1] < tags[i] ) : "expecting sorted tags"; - } - assert assertTreeSubTypeOf(otherwise, type); - Switch tree = make.Switch(pos, test, tags, bodies, otherwise); - tree.setType(type); - return tree; - } - public Switch Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise, - Type type) - { - return Switch(test.pos, test, tags, bodies, otherwise, type); - } - - /** Builds a Switch node with given components. */ - public Switch Switch(int pos, Tree test, int[] tags, Tree[] bodies, - Tree otherwise) - { - Type[] types = new Type[bodies.length + 1]; - for (int i = 0; i < bodies.length; i++) types[i] = bodies[i].getType(); - types[bodies.length] = otherwise.getType(); - global.nextPhase(); - Type type = Type.lub(types); - global.prevPhase(); - return Switch(pos, test, tags, bodies, otherwise, type); - } - public Switch Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise){ - return Switch(test.pos, test, tags, bodies, otherwise); - } - - /** Builds a Return node of given method with given value. */ - public Return Return(int pos, Symbol method, Tree value) { - Return tree = make.Return(pos, method, value); - tree.setType(definitions.ALL_TYPE()); - return tree; - } - public Return Return(Symbol method, Tree value) { - return Return(value.pos, method, value); - } - - /** Builds a Typed nodes with given value and type. */ - public Typed Typed(int pos, Tree value, Tree type) { - Typed tree = make.Typed(pos, value, type); - tree.setType(type.type()); - return tree; - } - public Typed Typed(Tree value, Tree type) { - return Typed(value.pos, value, type); - } - public Typed Typed(int pos, Tree value, Type type) { - return Typed(pos, value, mkType(pos, type)); - } - public Typed Typed(Tree value, Type type) { - return Typed(value.pos, value, type); - } - - //######################################################################## - // Public Methods - Building expressions - Lists - - /** Builds an empty list. */ - public Tree mkNil(int pos) { - return mkGlobalRef(pos, definitions.NIL()); - } - - /** Builds a list with given element type, head and tail. */ - public Tree mkNewCons(int pos, Type element, Tree head, Tree tail) { - // !!! these checks can be removed once they are done in Apply - global.nextPhase(); - assert head.type().isSubType(element): - element + " -- " + head + " : " + head.type; - assert tail.type().isSubType(definitions.LIST_TYPE(element)): - element + " -- " + tail + " : " + tail.type; - global.prevPhase(); - return New( - mkApplyTV( - mkPrimaryConstructorGlobalRef(pos, definitions.CONS_CLASS()), - new Type[]{element}, - new Tree[]{head, tail})); - } - public Tree mkNewCons(Type element, Tree head, Tree tail) { - return mkNewCons(head.pos, element, head, tail); - } - - /** Builds a list with given element type and values. */ - public Tree mkNewList(int pos, Type element, Tree[] values) { - Tree list = mkNil(pos); - for (int i = values.length - 1; 0 <= i; i--) - list = mkNewCons(pos, element, values[i], list); - return list; - } - - //######################################################################## - // Public Methods - Building expressions - Arrays - - /** Builds a new array tree with given element type and length. */ - public Tree mkNewArray(int pos, Type element, Tree length) { - return New( - mkApplyTV( - mkPrimaryConstructorGlobalRef(pos, definitions.ARRAY_CLASS), - new Type[]{element}, - new Tree[]{length})); - } - public Tree mkNewArray(Type element, Tree length) { - return mkNewArray(length.pos, element, length); - } - public Tree mkNewArray(int pos, Type element, int length) { - return mkNewArray(pos, element, mkIntLit(pos, length)); - } - - /** - * Builds a new array tree with given element type and values. The - * owner must be the owner of the created code. It is needed to - * create a local variable. - */ - public Tree mkNewArray(int pos, Type element, Tree[] values, Symbol owner){ - if (values.length == 0) return mkNewArray(pos, element, 0); - Tree[] trees = new Tree[1 + values.length]; - Symbol array = newLocal( - owner, pos, FINAL, "array", definitions.array_TYPE(element)); - trees[0] = ValDef(array, mkNewArray(pos, element, values.length)); - for (int i = 0; i < values.length; i++) - trees[1 + i] = mkArraySet(Ident(pos, array), i, values[i]); - return Block(pos, trees, Ident(pos, array)); - } - - /** Builds an array length operation. */ - public Tree mkArrayLength(int pos, Tree array) { - Tree function = Select(pos, array, definitions.ARRAY_LENGTH()); - return Apply(pos, function); - } - public Tree mkArrayLength(Tree array) { - return mkArrayLength(array.pos, array); - } - - /** Builds an array get operation. */ - public Tree mkArrayGet(int pos, Tree array, Tree index) { - Tree function = Select(pos, array, definitions.ARRAY_GET()); - return Apply(pos, function, new Tree[] {index}); - } - public Tree mkArrayGet(Tree array, Tree index) { - return mkArrayGet(array.pos, array, index); - } - public Tree mkArrayGet(int pos, Tree array, int index) { - return mkArrayGet(pos, array, mkIntLit(pos, index)); - } - public Tree mkArrayGet(Tree array, int index) { - return mkArrayGet(array.pos, array, index); - } - - /** Builds an array set operation. */ - public Tree mkArraySet(int pos, Tree array, Tree index, Tree value) { - Tree function = Select(pos, array, definitions.ARRAY_SET()); - return Apply(pos, function, new Tree[] {index, value}); - } - public Tree mkArraySet(Tree array, Tree index, Tree value) { - return mkArraySet(array.pos, array, index, value); - } - public Tree mkArraySet(int pos, Tree array, int index, Tree value) { - return mkArraySet(pos, array, mkIntLit(pos, index), value); - } - public Tree mkArraySet(Tree array, int index, Tree value) { - return mkArraySet(array.pos, array, index, value); - } - - //######################################################################## - // Public Methods - Building definitions - - /** Builds the type parameter section of given symbol. */ - public AbsTypeDef[] mkTypeParamsOf(Symbol sym) { - Symbol[] tparams = sym.nextTypeParams(); - AbsTypeDef[] trees = new AbsTypeDef[tparams.length]; - for (int i = 0; i < tparams.length; i++) - trees[i] = mkTypeParam(tparams[i]); - return trees; - } - - /** Builds the value parameter section of given symbol. */ - public ValDef[][] mkParamsOf(Symbol sym) { - global.nextPhase(); - if (sym.isClass()) sym = sym.primaryConstructor(); - Type type = sym.type(); - global.prevPhase(); - ValDef[][] treess = Tree.ValDef_EMPTY_ARRAY_ARRAY; - while (true) { - switch (type) { - case PolyType(_, Type result): - type = result; - continue; - case MethodType(Symbol[] vparams, Type result): - ValDef[] trees = new ValDef[vparams.length]; - for (int i = 0; i < vparams.length; i++) - trees[i] = mkParam(vparams[i]); - ValDef[][] array = new ValDef[treess.length + 1][]; - for (int i = 0; i < treess.length; i++) array[i] = treess[i]; - array[treess.length] = trees; - treess = array; - type = result; - continue; - default: - return treess; - } - } - } - - /** Builds the type parameter corresponding to given symbol. */ - public AbsTypeDef mkTypeParam(Symbol sym) { - return AbsTypeDef(sym); - } - - /** Builds the value parameter corresponding to given symbol. */ - public ValDef mkParam(Symbol sym) { - return ValDef(sym, Tree.Empty); - } - - /** Builds a PackageDef with given package and template. */ - public PackageDef PackageDef(Tree peckage, Template template) { - PackageDef tree = make.PackageDef(peckage.pos, peckage, template); - tree.setType(Type.NoType); - return tree; - } - public PackageDef PackageDef(Symbol peckage, Template template) { - return PackageDef(mkGlobalRef(peckage.pos, peckage), template); - } - - /** Builds a PackageDef with given package and body. */ - public PackageDef PackageDef(Tree peckage, Tree[] body) { - return PackageDef( - peckage, - Template(peckage.pos, Symbol.NONE, Tree.EMPTY_ARRAY, body)); - } - public PackageDef PackageDef(Symbol peckage, Tree[] body) { - return PackageDef(mkGlobalRef(peckage.pos, peckage), body); - } - - /** Builds a ClassDef node for given class with given template. */ - public ClassDef ClassDef(Symbol clazz, Template template) { - Tree type = Tree.Empty; - if (clazz.thisSym() != clazz) { - global.nextPhase(); - type = mkType(clazz.pos, clazz.typeOfThis()); - global.prevPhase(); - } - ClassDef tree = make.ClassDef( - clazz.pos, - clazz, - mkTypeParamsOf(clazz), - mkParamsOf(clazz), - type, - template); - tree.setType(Type.NoType); - return tree; - } - - /** - * Builds a ClassDef node for given class with given parent - * constructors, local symbol and body. - */ - public ClassDef ClassDef(Symbol clazz, Tree[] constrs, Symbol local, - Tree[] body) - { - return ClassDef(clazz, Template(clazz.pos, local, constrs, body)); - } - - /** Builds a ClassDef node for given class with given body. */ - public Tree ClassDef(Symbol clazz, Tree[] body) { - for (int i = 0; i < body.length; i++) { - assert body[i] == Tree.Empty - || body[i].definesSymbol() && body[i].symbol().owner() ==clazz: - "\nclass : " + Debug.show(clazz) + - "\nmember: " + Debug.show(body[i].symbol()) + - "\nmember: " + body[i]; - } - Global.instance.nextPhase(); - Type[] parents = clazz.parents(); - Global.instance.prevPhase(); - Tree[] constrs = new Tree[parents.length]; - for (int i = 0; i < constrs.length; i++) { - switch (parents[i]) { - case TypeRef(Type prefix, Symbol parent, Type[] targs): - constrs[i] = mkApplyT_( - mkPrimaryConstructorRef(clazz.pos, prefix, parent), - targs); - continue; - default: - throw Debug.abort("invalid type", parents[i]); - } - } - return ClassDef(clazz, constrs, Symbol.NONE, body); - } - - /** Builds a ValDef node for given symbol and with given rhs. */ - public ValDef ValDef(Symbol sym, Tree rhs) { - ValDef tree = make.ValDef( - sym.pos, - sym, - TypeTerm(sym.pos, sym.nextType()), - rhs); - tree.setType(Type.NoType); - return tree; - } - - /** Builds a DefDef node for given symbol with given body. */ - public DefDef DefDef(Symbol sym, Tree body) { - DefDef tree = make.DefDef( - sym.pos, - sym, - mkTypeParamsOf(sym), - mkParamsOf(sym), - TypeTerm(sym.pos, sym.nextType().resultType()), - body); - tree.setType(Type.NoType); - return tree; - } - - /** Builds an AbsTypeDef node for given symbol. */ - public AbsTypeDef AbsTypeDef(Symbol sym) { - AbsTypeDef tree = make.AbsTypeDef( - sym.pos, - sym, - TypeTerm(sym.pos, sym.isViewBounded() ? sym.vuBound() : sym.nextInfo()), - TypeTerm(sym.pos, sym.loBound())); - tree.setType(Type.NoType); - return tree; - } - - /** Builds an AliasTypeDef node for given symbol. */ - public AliasTypeDef AliasTypeDef(Symbol sym) { - AliasTypeDef tree = make.AliasTypeDef( - sym.pos, - sym, - mkTypeParamsOf(sym), - TypeTerm(sym.pos, sym.nextInfo())); - tree.setType(Type.NoType); - return tree; - } - - /** Builds an CaseDef node with given pattern, guard and body. */ - public CaseDef CaseDef(Tree pattern, Tree guard, Tree body) { - CaseDef tree = make.CaseDef(pattern.pos, pattern, guard, body); - tree.setType(body.getType()); - return tree; - } - - /** Builds an CaseDef node with given pattern and body. */ - public CaseDef CaseDef(Tree pattern, Tree body) { - return CaseDef(pattern, Tree.Empty, body); - } - - /** - * Builds a LabelDef node for given label with given parameters - * and body. - */ - public LabelDef LabelDef(Symbol label, Ident[] params, Tree body) { - LabelDef tree = make.LabelDef(label.pos, label, params, body); - tree.setType(label.nextType().resultType()); - return tree; - } - public LabelDef LabelDef(Symbol label, Symbol[] params, Tree body) { - Ident[] idents = new Ident[params.length]; - for (int i = 0; i < params.length; i++) - idents[i] = Ident(params[i].pos, params[i]); - return LabelDef(label, idents, body); - } - - //######################################################################## - // Private Methods - - /** Asserts type of given tree is a subtype of given type. */ - private boolean assertTreeSubTypeOf(Tree tree, Type expected) { - global.nextPhase(); - assert tree.getType().isSubType(expected): - "\ntree : " + tree + - "\ntype : " + tree.getType() + - "\nexpected: " + expected; - global.prevPhase(); - return true; - } - - /** Creates a new local variable and initializes it. */ - private Symbol newLocal(Symbol owner, int pos, int flags, String prefix, - Type type) - { - Name name = Names.LOCAL(owner); // !!! create unique names ? - flags |= Modifiers.SYNTHETIC; - Symbol local = owner.newVariable(pos, flags, name); - global.nextPhase(); - local.setType(type); - global.prevPhase(); - return local; - } - - /** Returns the primary constructor of given class. */ - private Symbol primaryConstructorOf(Symbol clasz) { - global.nextPhase(); - Symbol constr = clasz.primaryConstructor(); - global.prevPhase(); - return constr; - } - - //######################################################################## - //######################################################################## - //######################################################################## - - //######################################################################## - // !!! not yet reviewed - - /** Build the expansion of (() => expr) - */ - public Tree mkUnitFunction(Tree expr, Type type, Symbol owner, - boolean tagMethod) - { - return mkFunction - (expr.pos, Tree.ValDef_EMPTY_ARRAY, expr, type, owner, tagMethod); - } - - /** Build the expansion of ((vparams_1, ..., vparams_n) => body) - * with result type `restype', where `owner' is the previous owner - * of `body'. - * This is: - * { class $anon() extends scala.Object with - * scala.Function_N[T_1, ..., T_n, restype] { - * def apply(vparams_1, ..., vparams_n) = body1 - * } - * new $anon() - * } - * where - * vparams_i: T_i - * `body1' results from `body' by changing owner of all defined - * symbols in `body' from `owner' to the apply method. - */ - public Tree mkFunction(int pos, ValDef[] vparams, Tree body, Type restype, - Symbol owner, boolean tagMethod) - { - int n = vparams.length; - Symbol[] params = new Symbol[n]; - Type[] argtypes = new Type[n]; - for (int i = 0; i < n; i++) { - params[i] = vparams[i].symbol(); - argtypes[i] = params[i].type(); - } - Type[] parentTypes = { - definitions.ANYREF_TYPE(), - definitions.FUNCTION_TYPE(argtypes, restype) }; - Name name = Names.ANON_CLASS_NAME.toTypeName(); - ClassSymbol clazz = owner.newAnonymousClass(pos, name); - clazz.setInfo(Type.compoundType(parentTypes, new Scope(), clazz)); - clazz.allConstructors().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); - global.addAttribute(clazz, definitions.SCALA_SERIALIZABLE_CONSTR); - Symbol applyMeth = clazz.newMethod(pos, FINAL, Names.apply) - .setInfo(Type.MethodType(params, restype)); - clazz.info().members().enter(applyMeth); - - for (int i = 0; i < params.length; i++) { - params[i].setOwner(applyMeth); - } - changeOwner(body, owner, applyMeth); - Tree[] memberTrees = new Tree[tagMethod ? 2 : 1]; - memberTrees[0] = DefDef(applyMeth, body); - if (tagMethod) - memberTrees[1] = mkTagMethod(clazz); - Tree classDef = ClassDef(clazz, memberTrees); - Tree alloc = New(mkApply__(mkPrimaryConstructorLocalRef(pos, clazz))); - return mkBlock(classDef, Typed(alloc, parentTypes[1])); // !!! Typed - } - - public Tree mkTagMethod(ClassSymbol clazz) { - int flags = - clazz.isSubClass(definitions.SCALAOBJECT_CLASS) ? OVERRIDE : 0; - Symbol tagSym = clazz.newMethod(clazz.pos, flags, Names.tag) - .setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, definitions.int_TYPE())); - clazz.info().members().enter(tagSym); - int tagValue = clazz.isCaseClass() ? clazz.tag() : 0; - return DefDef(tagSym, mkIntLit(clazz.pos, tagValue)); - } - - public Tree mkPartialFunction(int pos, Tree applyVisitor, Tree isDefinedAtVisitor, - Type pattype, Type restype, Symbol owner) { - Name name = Names.ANON_CLASS_NAME.toTypeName(); - Symbol clazz = owner.newAnonymousClass(pos, name); - Type[] parentTypes = { - definitions.ANYREF_TYPE(), - definitions.PARTIALFUNCTION_TYPE(pattype, restype)}; - clazz.setInfo(Type.compoundType(parentTypes, new Scope(), clazz)); - clazz.allConstructors().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); - Tree[] memberTrees = { - makeVisitorMethod(pos, Names.apply, applyVisitor, - pattype, restype, clazz, owner), - makeVisitorMethod(pos, Names.isDefinedAt, isDefinedAtVisitor, - pattype, definitions.boolean_TYPE(), clazz, owner)}; - Tree classDef = ClassDef(clazz, memberTrees); - Tree alloc = New(mkApply__(mkPrimaryConstructorLocalRef(pos, clazz))); - return mkBlock(classDef, Typed(alloc, parentTypes[1])); // !!! Typed - } - //where - private Tree makeVisitorMethod(int pos, Name name, Tree visitor, - Type pattype, Type restype, - Symbol clazz, Symbol prevOwner) { - Symbol meth = clazz.newMethod(pos, FINAL, name); - Symbol param = meth.newVParam(pos, 0, Name.fromString("x$"), pattype); - meth.setInfo(Type.MethodType(new Symbol[]{param}, restype)); - clazz.info().members().enter(meth); - changeOwner(visitor, prevOwner, meth); - Tree body = - mkApplyTV( - Select(Ident(pos, param), definitions.ANY_MATCH), - new Tree[]{mkType(pos, pattype), mkType(pos, restype)}, - new Tree[]{visitor}); - return DefDef(meth, body); - } - - /** Change owner of all defined symbols from `prevOwner' to `newOwner' - */ - public void changeOwner(Tree tree, final Symbol prevOwner, final Symbol newOwner) { - Traverser lifter = new Traverser() { - public void traverse(Tree tree) { - if (tree.definesSymbol()) { - Symbol sym = tree.symbol(); - if (sym != null && sym.owner() == prevOwner) { - sym.setOwner(newOwner); - } - } - super.traverse(tree); - } - }; - lifter.traverse(tree); - } - - /** Build a postfix function application - */ - public Tree postfixApply(Tree obj, Tree fn, Symbol owner) { - if (TreeInfo.isPureExpr(obj) || TreeInfo.isPureExpr(fn)) { - return Apply(Select(fn, definitions.FUNCTION_APPLY(1)), new Tree[]{obj}); - } else { - Symbol tmp = newLocal(owner, obj.pos, FINAL, "postfix", obj.type); - Tree expr = postfixApply(Ident(obj.pos, tmp), fn, owner); - return mkBlock(ValDef(tmp, obj), expr); - } - } - - // for insert debug printing code - - public Tree Console_print(int pos, String str) { - return Console_print( pos, mkStringLit( pos, str )); - } - - public Tree Console_print(int pos, Tree arg) { - return Apply( Select( pos, - mkGlobalRef(pos, definitions.CONSOLE), - definitions.CONSOLE_PRINT()), - new Tree[] { - arg - }); - } - -} diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java deleted file mode 100644 index caeb7d72c0..0000000000 --- a/sources/scalac/ast/TreeInfo.java +++ /dev/null @@ -1,307 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.ast; - -import scalac.ApplicationError; -import scalac.util.Name; -import scalac.util.Names; -import scalac.symtab.Type; -import scalac.symtab.Symbol; -import scalac.symtab.Modifiers; - -import java.util.LinkedList; - -public class TreeInfo { - - public static boolean isTerm(Tree tree) { - return tree.isTerm(); - } - - public static boolean isType(Tree tree) { - return tree.isType(); - } - - public static boolean isOwnerDefinition(Tree tree) { - switch (tree) { - case PackageDef(_, _): - case ClassDef(_, _, _, _, _, _): - case ModuleDef(_, _, _, _): - case DefDef(_, _, _, _, _, _): - case Import(_, _): - return true; - default: - return false; - } - } - - public static boolean isDefinition(Tree tree) { - switch (tree) { - case PackageDef(_, _): - case ClassDef(_, _, _, _, _, _): - case ModuleDef(_, _, _, _): - case DefDef(_, _, _, _, _, _): - case ValDef(_, _, _, _): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case Import(_, _): - return true; - default: - return false; - } - } - - public static boolean isDeclaration(Tree tree) { - switch (tree) { - case DefDef(_, _, _, _, _, Tree rhs): - return rhs == Tree.Empty; - case ValDef(_, _, _, Tree rhs): - return rhs == Tree.Empty; - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - return true; - default: - return false; - } - } - - /** Is tree a pure definition? - */ - public static boolean isPureDef(Tree tree) { - switch (tree) { - case Tree.Empty: - case ClassDef(_, _, _, _, _, _): - case ModuleDef(_, _, _, _): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case Import(_, _): - return true; - case DefDef(_, Name name, _, _, _, _): - return name != Names.CONSTRUCTOR; - case ValDef(int mods, _, _, Tree rhs): - return (mods & Modifiers.MUTABLE) == 0 && isPureExpr(rhs); - case DocDef(_, Tree definition): - return isPureDef(definition); - default: - return false; - } - } - - /** Is tree a stable & pure expression? - */ - public static boolean isPureExpr(Tree tree) { - switch (tree) { - case Empty: - case This(_): - case Super(_, _): - return true; - case Ident(_): - assert tree.type != null : tree.toString(); - return tree.symbol().isStable(); - case Select(Tree qual, _): - return tree.symbol().isStable() && isPureExpr(qual); - case Apply(Tree fn, Tree[] args): - return isPureExpr(fn) && args.length == 0; - case TypeApply(Tree fn, Tree[] targs): - return isPureExpr(fn); - case Typed(Tree expr, _): - return isPureExpr(expr); - case Literal(_): - return true; - default: - return false; - } - } - - /** Is tree a pure constructor? - */ - public static boolean isPureConstr(Tree tree) { - switch (tree) { - case Ident(_): - case Select(_, _): - return tree.symbol() != null && tree.symbol().isPrimaryConstructor(); - case TypeApply(Tree constr, _): - return isPureConstr(constr); - case Apply(Tree fn, Tree[] args): - return args.length == 0 && isPureConstr(fn); - default: - return false; - } - } - - /** Is tree a self constructor call? - */ - public static boolean isSelfConstrCall(Tree tree) { - switch (tree) { - case Ident(Name name): - return name == Names.CONSTRUCTOR; - case TypeApply(Tree constr, _): - return isSelfConstrCall(constr); - case Apply(Tree constr, _): - return isSelfConstrCall(constr); - default: - return false; - } - } - - /** Is tree a variable pattern - */ - public static boolean isVarPattern(Tree pat) { - switch (pat) { - case Ident(Name name): - return name.isVariable(); - default: - return false; - } - } - - /** Is tree a this node which belongs to `enclClass'? - */ - public static boolean isSelf(Tree tree, Symbol enclClass) { - switch (tree) { - case This(_): - return tree.symbol() == enclClass; - default: - return false; - } - } - - /** The method symbol of an application node, or Symbol.NONE, if none exists. - */ - public static Symbol methSymbol(Tree tree) { - Tree meth = methPart(tree); - if (meth.hasSymbol()) return meth.symbol(); - else return Symbol.NONE; - } - - /** The method part of an application node - */ - public static Tree methPart(Tree tree) { - switch (tree) { - case Apply(Tree fn, _): - return methPart(fn); - case TypeApply(Tree fn, _): - return methPart(fn); - case AppliedType(Tree fn, _): - return methPart(fn); - default: - return tree; - } - } - - /** The symbol with name `name' imported from import clause `tree'. - */ - public static Symbol importedSymbol(Tree tree, Name name) { - switch (tree) { - case Import(Tree expr, Name[] selectors): - Type pre = tree.symbol().type(); - if (pre != Type.ErrorType) { - boolean renamed = false; - for (int i = 0; i < selectors.length; i = i + 2) { - if (i + 1 < selectors.length && name.toTermName() == selectors[i + 1]) { - if (name.isTypeName()) - return pre.lookupNonPrivate(selectors[i].toTypeName()); - else - return pre.lookupNonPrivate(selectors[i]); - } else if (name.toTermName() == selectors[i]) { - renamed = true; - } else if (selectors[i] == Names.IMPORT_WILDCARD && !renamed) { - return pre.lookupNonPrivate(name); - } - } - } - return Symbol.NONE; - default: - throw new ApplicationError(); - } - } - - - /** returns true if the tree is a sequence-valued pattern. - * precondition: tree is a pattern. - * calls isSequenceValued( Tree, List ) because needs to remember bound - * values. - */ - public static boolean isSequenceValued( Tree tree ) { - return isSequenceValued( tree, new LinkedList() ); - } - - /** returns true if the tree is a sequence-valued pattern. - * precondition: tree is a pattern - */ - public static boolean isSequenceValued( Tree tree, LinkedList recVars ) { - switch( tree ) { - case Bind(_, Tree t): - recVars.addFirst( tree.symbol() ); - boolean res = isSequenceValued( t ); - recVars.removeFirst(); - return res; - case Sequence(_): - return true; - case Alternative(Tree[] ts): - for( int i = 0; i < ts.length; i++ ) { - if( isSequenceValued( ts[ i ] ) ) - return true; - } - return false; - case Ident(Name n): // if Ident is a recursive var, then true - return recVars.contains( tree.symbol() ); - case Apply( _, _ ): - case Literal( _ ): - case Select(_,_): - case Typed(_,_): - return false; - default: - throw new scalac.ApplicationError("Unexpected pattern "+tree.getClass()); - } - } - - /** returns true if the argument is an empty sequence pattern - */ - public static boolean isEmptySequence( Tree tree ) { - switch( tree ) { - case Sequence( Tree ts[] ): - return ( ts.length == 0 ); - default: - return false; - } - } - /** this test should correspond to the one used in TransMatch phase */ - public static boolean isRegularPattern( Tree tree ) { - switch (tree) { - case Alternative(_): - return true; - case Bind(_, Tree pat): - return isRegularPattern( pat ); - case Ident(_): - return false; - case CaseDef(Tree pat, _, _): - isRegularPattern(pat); - break; - case Sequence( Tree[] trees): - return true; - case Apply( _, Tree[] trees ): - for( int i = 0; i < trees.length; i++ ) - if( isRegularPattern( trees[i] ) ) - return true; - case Literal( _ ): - return false; - - } - return false; - } - - /** @todo replace with cleaner test (e.g. of a symbol flag) - */ - public static boolean isNameOfStarPattern( Name n ) { - String s = n.toString(); - return (s.indexOf("$") != -1) - &&(!s.startsWith("nest")); - } - -} diff --git a/sources/scalac/ast/TreeList.java b/sources/scalac/ast/TreeList.java deleted file mode 100644 index bf4550c632..0000000000 --- a/sources/scalac/ast/TreeList.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -package scalac.ast; - -/** List of trees. - */ - -public final class TreeList { - Tree[] trees; - int len; - - public TreeList(Tree[] ts) { - trees = ts; - len = ts.length; - } - - public TreeList() { - clear(); - } - - public void append(Tree tree) { - if (len == trees.length) { - Tree[] ts = new Tree[len == 0 ? 4 : len * 2]; - System.arraycopy(trees, 0, ts, 0, len); - trees = ts; - } - trees[len++] = tree; - } - - public void append(Tree[] ts) { - for (int j = 0; j < ts.length; j++) - append(ts[j]); - } - - public void append(TreeList tl) { - for (int j = 0; j < tl.len; j++) - append(tl.trees[j]); - } - - public void clear() { - trees = new Tree[4]; - len = 0; - } - - public int length() { - return len; - } - - public Tree get(int i) { - return trees[i]; - } - - public Tree first() { - return trees[0]; - } - - public Tree removeLast() { - return trees[--len]; - } - - public Tree[] toArray() { - Tree[] ts = new Tree[len]; - System.arraycopy(trees, 0, ts, 0, len); - return ts; - } - - public Tree[] copyTo(Tree[] ts) { - return copyTo(ts, 0); - } - - public Tree[] copyTo(Tree[] ts, int from) { - System.arraycopy(trees, 0, ts, from, len); - return ts; - } -} diff --git a/sources/scalac/ast/printer/TreePrinter.java b/sources/scalac/ast/printer/TreePrinter.java deleted file mode 100644 index a0884b0b2a..0000000000 --- a/sources/scalac/ast/printer/TreePrinter.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast.printer; - -import scalac.Global; -import scalac.CompilationUnit; -import scalac.ast.Tree; - -/** - * Interface for all abstract tree printers. - * - * @author Michel Schinz - * @version 1.0 - */ -public interface TreePrinter { - public void begin(); - public void end(); - public void flush(); - - public void print(CompilationUnit[] units); - public void print(Tree tree); -} diff --git a/sources/scalac/atree/AArithmeticOp.java b/sources/scalac/atree/AArithmeticOp.java deleted file mode 100644 index 1627ca1ad9..0000000000 --- a/sources/scalac/atree/AArithmeticOp.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents an arithmetic operation. */ -public class AArithmeticOp { - - //######################################################################## - // Public Cases - - /** An arithmetic addition operation */ - public case ADD; - - /** An arithmetic subtraction operation */ - public case SUB; - - /** An arithmetic multiplication operation */ - public case MUL; - - /** An arithmetic division operation */ - public case DIV; - - /** An arithmetic remainder operation */ - public case REM; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case ADD: return "ADD"; - case SUB: return "SUB"; - case MUL: return "MUL"; - case DIV: return "DIV"; - case REM: return "REM"; - default : throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AClass.java b/sources/scalac/atree/AClass.java deleted file mode 100644 index 66cf4693e1..0000000000 --- a/sources/scalac/atree/AClass.java +++ /dev/null @@ -1,139 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import java.util.Map; -import java.util.LinkedHashMap; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** This class represents an attributed class. */ -public class AClass extends ARepository { - - //######################################################################## - // Private Fields - - /** The class symbol */ - private final Symbol symbol; - - /** The symbol to field map */ - private final Map/*<Symbol,AField>*/ fields; - - /** The symbol to method map */ - private final Map/*Symbol,AMethod*/ methods; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AClass(Symbol symbol) { - this.symbol = symbol; - this.fields = new LinkedHashMap(); - this.methods = new LinkedHashMap(); - } - - //######################################################################## - // Public Methods - - /** Returns the symbol of this class. */ - public Symbol symbol() { - return symbol; - } - - /** Is this class public? */ - public boolean isPublic() { - return symbol().isPublic(); - } - - /** Is this class private? */ - public boolean isPrivate() { - return symbol().isPrivate(); - } - - /** Is this class protected? */ - public boolean isProtected() { - return symbol().isProtected(); - } - - /** Is this class final? */ - public boolean isFinal() { - return false; // !!! - } - - /** Is this class abstract? */ - public boolean isAbstract() { - return symbol.isAbstractClass(); - } - - /** Is this class an interface? */ - public boolean isInterface() { - return symbol.isInterface(); - } - - /** Is this class deprecated? */ - public boolean isDeprecated() { - return false; // !!! - } - - /** Is this class synthetic? */ - public boolean isSynthetic() { - return symbol().isSynthetic(); - } - - /** Adds the given field to this class. */ - public void addField(AField field) { - assert !fields.containsKey(field.symbol()): field; - fields.put(field.symbol(), field); - } - - /** Adds the given method to this class. */ - public void addMethod(AMethod method) { - assert !methods.containsKey(method.symbol()): method; - methods.put(method.symbol(), method); - } - - /** Returns the fields of this class. */ - public AField[] fields() { - return (AField[])fields.values().toArray(new AField[fields.size()]); - } - - /** Returns the methods of this class. */ - public AMethod[] methods() { - return(AMethod[])methods.values().toArray(new AMethod[methods.size()]); - } - - /** Returns the type parameters of this class. */ - public Symbol[] tparams() { - return symbol.typeParams(); - } - - /** Returns the value parameters of this class. */ - public Symbol[] vparams() { - return symbol.valueParams(); - } - - /** Returns the parent types of this class. */ - public Type[] parents() { - switch (symbol.info()) { - case CompoundType(Type[] parts, _): - return parts; - default: - throw Debug.abort("illegal case", symbol.info()); - } - } - - /** Returns a string representation of this class. */ - public String toString() { - return new ATreePrinter().printClass(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ACode.java b/sources/scalac/atree/ACode.java deleted file mode 100644 index 3e65d41829..0000000000 --- a/sources/scalac/atree/ACode.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** This class represents attributed code. */ -public class ACode { - - //######################################################################## - // Public Constants - - public static final ACode[] EMPTY_ARRAY = new ACode[0]; - - //######################################################################## - // Public Cases - - // jvm : - - public case Void; - - // jvm : aload_0 - public case This(Symbol clasz); - - // jvm : {b, s}ipush, ldc{ ,_w, 2_w}, aconst_null - // jvm : iconst_{m1, 2, 3, 4, 5}, {i, l, f, d}const_{0, 1}, fconst_2 - public case Constant(AConstant constant); - - // jvm : get{static, field} - // jvm : {i, l, f, d, a}load{, _0, _1, _2, _3} - // jvm : {i, l, f, d, a, b, c, s}aload - public case Load(ALocation location); - - // jvm : put{static, field} - // jvm : {i, l, f, d, a}store{, _0, _1, _2, _3} - // jvm : {i, l, f, d, a, b, c, s}store - public case Store(ALocation location, ACode value); - - // jvm : new, invoke{static, virtual, interface, special}, {, a}newarray - // jvm : <see also in APrimitive> - public case Apply(AFunction function, Type[] targs, ACode[] vargs); - - // jvm : instanceof, checkcast - public case IsAs(ACode value, Type type, boolean cast); - - // jvm : - - public case If(ACode test, ACode success, ACode failure); - - // jvm : {tables, lookup}switch - public case Switch(ACode test, int[][] tags, ACode[] bodies); - - // jvm : monitor{enter, exit} - public case Synchronized(ACode lock, ACode value); - - // jvm : - - public case Block(Symbol[] locals, ACode[] statements, ACode value); - - // jvm : - - public case Label(Symbol label, Symbol[] locals, ACode value); - - // jvm : goto, goto_w - public case Goto(Symbol label, ACode[] vargs); - - // jvm : {i, l, f, d, a, }return - public case Return(Symbol function, ACode value); - - // jvm : athrow - public case Throw(ACode value); - - // jvm : pop, pop2 - public case Drop(ACode value, Type type); - - // jvm : nop, dup{, _x1, _x2, 2, 2_x1, 2_x2}, swap - // jvm : multianewarray, iinc, jsr{, _w}, ret, wide - // NOT MAPPED - - //######################################################################## - // Public Fields - - /** The source file position */ - public int pos; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this code. */ - public String toString() { - return new ATreePrinter().printCode(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AComparisonOp.java b/sources/scalac/atree/AComparisonOp.java deleted file mode 100644 index 1e7bcf1bcd..0000000000 --- a/sources/scalac/atree/AComparisonOp.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a comparison operation. */ -public class AComparisonOp { - - //######################################################################## - // Public Cases - - /** A comparison operation with -1 default for NaNs */ - public case CMPL; - - /** A comparison operation with no default for NaNs */ - public case CMP; - - /** A comparison operation with +1 default for NaNs */ - public case CMPG; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case CMPL: return "CMPL"; - case CMP : return "CMP"; - case CMPG: return "CMPG"; - default : throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AConstant.java b/sources/scalac/atree/AConstant.java deleted file mode 100644 index 12c58d5889..0000000000 --- a/sources/scalac/atree/AConstant.java +++ /dev/null @@ -1,404 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; -import scalac.symtab.Symbol; - -/** This class represents a constant. */ -public class AConstant { - - public static final AConstant[] EMPTY_ARRAY = new AConstant[0]; - - //######################################################################## - // Public Cases - - public case UNIT; - public case BOOLEAN(boolean value); - public case BYTE(byte value); - public case SHORT(short value); - public case CHAR(char value); - public case INT(int value); - public case LONG(long value); - public case FLOAT(float value); - public case DOUBLE(double value); - public case STRING(String value); - public case SYMBOL_NAME(Symbol value); - public case NULL; - public case ZERO; - - //######################################################################## - // Public Methods - - /** Returns the type kind of this constant. */ - public ATypeKind kind() { - switch (this) { - case UNIT: - return ATypeKind.UNIT; - case BOOLEAN(_): - return ATypeKind.BOOL; - case BYTE(_): - return ATypeKind.I1; - case SHORT(_): - return ATypeKind.I2; - case CHAR(_): - return ATypeKind.U2; - case INT(_): - return ATypeKind.I4; - case LONG(_): - return ATypeKind.I8; - case FLOAT(_): - return ATypeKind.R4; - case DOUBLE(_): - return ATypeKind.R8; - case STRING(_): - case SYMBOL_NAME(_): - return ATypeKind.STR; - case NULL: - return ATypeKind.NULL; - case ZERO: - return ATypeKind.ZERO; - default: - throw Debug.abort("unknown case", this); - } - } - - - /** Converts this constant to a boolean value. */ - public boolean booleanValue() { - switch (this) { - case BOOLEAN(boolean value): - return value; - default: - throw Debug.abort("not convertible to boolean", this); - } - } - - /** Converts this constant to a byte value. */ - public byte byteValue() { - switch (this) { - case BYTE(byte value): - return (byte)value; - case SHORT(short value): - return (byte)value; - case CHAR(char value): - return (byte)value; - case INT(int value): - return (byte)value; - case LONG(long value): - return (byte)value; - case FLOAT(float value): - return (byte)value; - case DOUBLE(double value): - return (byte)value; - default: - throw Debug.abort("not convertible to byte", this); - } - } - - /** Converts this constant to a short value. */ - public short shortValue() { - switch (this) { - case BYTE(byte value): - return (short)value; - case SHORT(short value): - return (short)value; - case CHAR(char value): - return (short)value; - case INT(int value): - return (short)value; - case LONG(long value): - return (short)value; - case FLOAT(float value): - return (short)value; - case DOUBLE(double value): - return (short)value; - default: - throw Debug.abort("not convertible to short", this); - } - } - - /** Converts this constant to a char value. */ - public char charValue() { - switch (this) { - case BYTE(byte value): - return (char)value; - case SHORT(short value): - return (char)value; - case CHAR(char value): - return (char)value; - case INT(int value): - return (char)value; - case LONG(long value): - return (char)value; - case FLOAT(float value): - return (char)value; - case DOUBLE(double value): - return (char)value; - default: - throw Debug.abort("not convertible to char", this); - } - } - - /** Converts this constant to a int value. */ - public int intValue() { - switch (this) { - case BYTE(byte value): - return (int)value; - case SHORT(short value): - return (int)value; - case CHAR(char value): - return (int)value; - case INT(int value): - return (int)value; - case LONG(long value): - return (int)value; - case FLOAT(float value): - return (int)value; - case DOUBLE(double value): - return (int)value; - default: - throw Debug.abort("not convertible to int", this); - } - } - - /** Converts this constant to a long value. */ - public long longValue() { - switch (this) { - case BYTE(byte value): - return (long)value; - case SHORT(short value): - return (long)value; - case CHAR(char value): - return (long)value; - case INT(int value): - return (long)value; - case LONG(long value): - return (long)value; - case FLOAT(float value): - return (long)value; - case DOUBLE(double value): - return (long)value; - default: - throw Debug.abort("not convertible to long", this); - } - } - - /** Converts this constant to a float value. */ - public float floatValue() { - switch (this) { - case BYTE(byte value): - return (float)value; - case SHORT(short value): - return (float)value; - case CHAR(char value): - return (float)value; - case INT(int value): - return (float)value; - case LONG(long value): - return (float)value; - case FLOAT(float value): - return (float)value; - case DOUBLE(double value): - return (float)value; - default: - throw Debug.abort("not convertible to float", this); - } - } - - /** Converts this constant to a double value. */ - public double doubleValue() { - switch (this) { - case BYTE(byte value): - return (double)value; - case SHORT(short value): - return (double)value; - case CHAR(char value): - return (double)value; - case INT(int value): - return (double)value; - case LONG(long value): - return (double)value; - case FLOAT(float value): - return (double)value; - case DOUBLE(double value): - return (double)value; - default: - throw Debug.abort("not convertible to double", this); - } - } - - /** Converts this constant to a String value. */ - public String stringValue() { - switch (this) { - case UNIT: - return "()"; - case BOOLEAN(boolean value): - return String.valueOf(value); - case BYTE(byte value): - return String.valueOf(value); - case SHORT(short value): - return String.valueOf(value); - case CHAR(char value): - return String.valueOf(value); - case INT(int value): - return String.valueOf(value); - case LONG(long value): - return String.valueOf(value); - case FLOAT(float value): - return String.valueOf(value); - case DOUBLE(double value): - return String.valueOf(value); - case STRING(String value): - return value; - case SYMBOL_NAME(Symbol value): - return value.name.toString(); - case NULL: - return String.valueOf(null); - default: - throw Debug.abort("not convertible to String", this); - } - } - - /** Tests whether this constant equals given Object. */ - public boolean equals(Object that) { - if (this == that) return true; - return (that instanceof AConstant) && this.equals((AConstant)that); - } - - /** Tests whether this constant equals given one. */ - public boolean equals(AConstant that) { - if (this == that) return true; - if (null == that) return false; - switch (this) { - case UNIT: - return false; - case BOOLEAN(boolean ivalue): - switch (that) { - case BOOLEAN(boolean avalue): - return ivalue == avalue; - default: - return false; - } - case BYTE(byte ivalue): - switch (that) { - case BYTE(byte avalue): - return ivalue == avalue; - default: - return false; - } - case SHORT(short ivalue): - switch (that) { - case SHORT(short avalue): - return ivalue == avalue; - default: - return false; - } - case CHAR(char ivalue): - switch (that) { - case CHAR(char avalue): - return ivalue == avalue; - default: - return false; - } - case INT(int ivalue): - switch (that) { - case INT(int avalue): - return ivalue == avalue; - default: - return false; - } - case LONG(long ivalue): - switch (that) { - case LONG(long avalue): - return ivalue == avalue; - default: - return false; - } - case FLOAT(float ivalue): - switch (that) { - case FLOAT(float avalue): - return ivalue == avalue; - default: - return false; - } - case DOUBLE(double ivalue): - switch (that) { - case DOUBLE(double avalue): - return ivalue == avalue; - default: - return false; - } - case STRING(String ivalue): - switch (that) { - case STRING(String avalue): - return ivalue.equals(avalue); - default: - return false; - } - case SYMBOL_NAME(Symbol ivalue): - switch (that) { - case SYMBOL_NAME(Symbol avalue): - return ivalue == avalue; - default: - return false; - } - case NULL: - return false; - case ZERO: - return false; - default: - throw Debug.abort("unknown case", this); - } - } - - /** Returns the hash code of this constant. */ - public int hashCode() { - switch (this) { - case UNIT: - return 4041; - case BOOLEAN(boolean value): - return value ? 1231 : 1237; - case BYTE(byte value): - return value; - case SHORT(short value): - return value; - case CHAR(char value): - return value; - case INT(int value): - return value; - case LONG(long value): - long bits = value; - return (int)(bits ^ (bits >>> 32)); - case FLOAT(float value): - int bits = java.lang.Float.floatToIntBits(value); - return bits; - case DOUBLE(double value): - long bits = java.lang.Double.doubleToLongBits(value); - return (int)(bits ^ (bits >>> 32)); - case STRING(String value): - return value.hashCode(); - case SYMBOL_NAME(Symbol value): - return value.hashCode(); - case NULL: - return 0; - case ZERO: - return 0; - default: - throw Debug.abort("unknown case", this); - } - } - - /** Returns a string representation of this constant. */ - public String toString() { - return new ATreePrinter().printConstant(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AField.java b/sources/scalac/atree/AField.java deleted file mode 100644 index bbc27f7063..0000000000 --- a/sources/scalac/atree/AField.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** This class represents an attributed field. */ -public class AField extends AMember { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AField(Symbol symbol, boolean isStatic) { - super(symbol, isStatic); - } - - //######################################################################## - // Public Methods - - /** Is this field final? */ - public boolean isFinal() { - return false; // !!! - } - - /** Is this field volatile? */ - public boolean isVolatile() { - return false; // !!! - } - - /** Is this field transient? */ - public boolean isTransient() { - return false; // !!! - } - - /** Returns the type of this field. */ - public Type type() { - return symbol().type(); - } - - /** Returns a string representation of this field. */ - public String toString() { - return new ATreePrinter().printField(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AFunction.java b/sources/scalac/atree/AFunction.java deleted file mode 100644 index 2970222a2c..0000000000 --- a/sources/scalac/atree/AFunction.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Type; -import scalac.symtab.Symbol; - -/** This class represents an attributed function reference. */ -public class AFunction { - - //######################################################################## - // Public Cases - - public case Method(ACode object, Symbol method, AInvokeStyle style); - public case Primitive(APrimitive primitive); - public case NewArray(Type element); - - //######################################################################## - // Public Methods - - /** Returns a string representation of this function. */ - public String toString() { - return new ATreePrinter().printFunction(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AInvokeStyle.java b/sources/scalac/atree/AInvokeStyle.java deleted file mode 100644 index f833aad2f0..0000000000 --- a/sources/scalac/atree/AInvokeStyle.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a method invocation style. */ -public class AInvokeStyle { - - //######################################################################## - // Public Cases - - public case New; - public case Dynamic; - public case Static(boolean onInstance); - - //######################################################################## - // Public Constants - - public static final AInvokeStyle StaticClass = Static(false); - public static final AInvokeStyle StaticInstance = Static(true); - - //######################################################################## - // Public Methods - - /** Is this a new object creation? */ - public boolean isNew() { - switch (this) { - case New: - return true; - default: - return false; - } - } - - /** Is this a dynamic method call? */ - public boolean isDynamic() { - switch (this) { - case Dynamic: - return true; - default: - return false; - } - } - - /** Is this a static method call? */ - public boolean isStatic() { - switch (this) { - case Static(_): - return true; - default: - return false; - } - } - - /** Is this an instance method call? */ - public boolean hasInstance() { - switch (this) { - case Dynamic: - return true; - case Static(boolean onInstance): - return onInstance; - default: - return false; - } - } - - /** Returns a string representation of this style. */ - public String toString() { - switch (this) { - case New: - return "new"; - case Dynamic: - return "dynamic"; - case Static(false): - return "static-class"; - case Static(true): - return "static-instance"; - default: - throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ALocation.java b/sources/scalac/atree/ALocation.java deleted file mode 100644 index 0a9c440df2..0000000000 --- a/sources/scalac/atree/ALocation.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; - -/** This class represents an attributed value location. */ -public class ALocation { - - //######################################################################## - // Public Cases - - public case Module(Symbol module); // !!! remove ? - public case Field(ACode object, Symbol field, boolean isStatic); - public case Local(Symbol local, boolean isArgument); - public case ArrayItem(ACode array, ACode index); - - //######################################################################## - // Public Methods - - /** Returns a string representation of this location. */ - public String toString() { - return new ATreePrinter().printLocation(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ALogicalOp.java b/sources/scalac/atree/ALogicalOp.java deleted file mode 100644 index 85010ae4f0..0000000000 --- a/sources/scalac/atree/ALogicalOp.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a logical operation. */ -public class ALogicalOp { - - //######################################################################## - // Public Cases - - /** A bitwise AND operation */ - public case AND; - - /** A bitwise OR operation */ - public case OR; - - /** A bitwise XOR operation */ - public case XOR; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case AND: return "AND"; - case OR : return "OR"; - case XOR: return "XOR"; - default : throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AMember.java b/sources/scalac/atree/AMember.java deleted file mode 100644 index 4275180a4d..0000000000 --- a/sources/scalac/atree/AMember.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; - -/** This class represents an attributed class member. */ -public abstract class AMember { - - //######################################################################## - // Private Fields - - /** The member symbol */ - private final Symbol symbol; - - /** The static flag */ - private final boolean isStatic; - - /** The member code */ - private ACode code; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AMember(Symbol symbol, boolean isStatic) { - this.symbol = symbol; - this.isStatic = isStatic; - this.code = ACode.Void; - } - - //######################################################################## - // Public Methods - - /** Returns the symbol of this member. */ - public Symbol symbol() { - return symbol; - } - - /** Is this member public? */ - public boolean isPublic() { - return symbol().isPublic(); - } - - /** Is this member private? */ - public boolean isPrivate() { - return symbol().isPrivate(); - } - - /** Is this member protected? */ - public boolean isProtected() { - return symbol().isProtected(); - } - - /** Is this member static? */ - public boolean isStatic() { - return isStatic; - } - - /** Is this member deprecated? */ - public boolean isDeprecated() { - return false; // !!! - } - - /** Is this member synthetic? */ - public boolean isSynthetic() { - return symbol().isSynthetic(); - } - - /** Returns the member code. */ - public ACode code() { - return code; - } - - /** Sets the member code. */ - public void setCode(ACode code) { - this.code = code; - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AMethod.java b/sources/scalac/atree/AMethod.java deleted file mode 100644 index f904fa6b92..0000000000 --- a/sources/scalac/atree/AMethod.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** This class represents an attributed method. */ -public class AMethod extends AMember { - //######################################################################## - // Public Fields - - /** Contains the Intermediate code of this Method */ - public Object icode = null; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AMethod(Symbol symbol, boolean isStatic) { - super(symbol, isStatic); - } - - //######################################################################## - // Public Methods - - /** Is this method final? */ - public boolean isFinal() { - return symbol().isMethodFinal(); - } - - /** Is this method synchronized? */ - public boolean isSynchronized() { - return false; // !!! - } - - /** Is this method native? */ - public boolean isNative() { - return false; // !!! - } - - /** Is this method abstract? */ - public boolean isAbstract() { - return symbol().isDeferred(); - } - - /** Is this method FP-strict? */ - public boolean isStrictFP() { - return false; // !!! - } - - /** Returns the type parameters of this method. */ - public Symbol[] tparams() { - return symbol().type().typeParams(); - } - - /** Returns the value parameters of this method. */ - public Symbol[] vparams() { - return symbol().type().valueParams(); - } - - /** Returns the result type of this method. */ - public Type result() { - return symbol().type().resultType(); - } - - /** Returns a string representation of this method. */ - public String toString() { - return new ATreePrinter().printMethod(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/APrimitive.java b/sources/scalac/atree/APrimitive.java deleted file mode 100644 index 034a9f4d19..0000000000 --- a/sources/scalac/atree/APrimitive.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -/** This class represents a primitive operation. */ -public class APrimitive { - - //######################################################################## - // Public Cases - - // type : (type) => type - // range: type <- { BOOL, Ix, Ux, Rx } - // jvm : {i, l, f, d}neg - public case Negation(ATypeKind kind); - - // type : zero ? (type) => BOOL : (type,type) => BOOL - // range: type <- { BOOL, Ix, Ux, Rx, REF } - // jvm : if{eq, ne, lt, ge, le, gt}, if{null, nonnull} - // if_icmp{eq, ne, lt, ge, le, gt}, if_acmp{eq,ne} - public case Test(ATestOp op, ATypeKind kind, boolean zero); - - // type : (type,type) => I4 - // range: type <- { Ix, Ux, Rx } - // jvm : lcmp, {f, d}cmp{l, g} - public case Comparison(AComparisonOp op, ATypeKind kind); - - // type : (type,type) => type - // range: type <- { Ix, Ux, Rx } - // jvm : {i, l, f, d}{add, sub, mul, div, rem} - public case Arithmetic(AArithmeticOp op, ATypeKind kind); - - // type : (type,type) => type - // range: type <- { BOOL, Ix, Ux } - // jvm : {i, l}{and, or, xor} - public case Logical(ALogicalOp op, ATypeKind kind); - - // type : (type,I4) => type - // range: type <- { Ix, Ux } - // jvm : {i, l}{shl, ushl, shr} - public case Shift(AShiftOp op, ATypeKind kind); - - // type : (src) => dst - // range: src,dst <- { Ix, Ux, Rx } - // jvm : i2{l, f, d}, l2{i, f, d}, f2{i, l, d}, d2{i, l, f}, i2{b, c, s} - public case Conversion(ATypeKind src, ATypeKind dst); - - // type : (Array[REF]) => I4 - // range: type <- { BOOL, Ix, Ux, Rx, REF } - // jvm : arraylength - public case ArrayLength(ATypeKind kind); - - // type : (lf,rg) => STR - // range: lf,rg <- { BOOL, Ix, Ux, Rx, REF, STR } - // jvm : - - public case StringConcat(ATypeKind lf, ATypeKind rg); - - //######################################################################## - // Public Methods - - /** Returns a string representation of this primitive. */ - public String toString() { - return new ATreePrinter().printPrimitive(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ARepository.java b/sources/scalac/atree/ARepository.java deleted file mode 100644 index c1468a85a8..0000000000 --- a/sources/scalac/atree/ARepository.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import java.util.Map; -import java.util.LinkedHashMap; - -/** This class represents a repository of attributed classes. */ -public class ARepository { - - //######################################################################## - // Private Fields - - /** The symbol to class map */ - private final Map/*<Symbol,AClass>*/ classes; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ARepository() { - this.classes = new LinkedHashMap(); - } - - //######################################################################## - // Public Methods - - /** Adds the given class to this repository. */ - public void addClass(AClass clasz) { - assert !classes.containsKey(clasz.symbol()): clasz; - classes.put(clasz.symbol(), clasz); - } - - /** Returns the classes of this repository. */ - public AClass[] classes() { - return (AClass[])classes.values().toArray(new AClass[classes.size()]); - } - - /** Returns a string representation of this repository. */ - public String toString() { - return new ATreePrinter().printRepository(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AShiftOp.java b/sources/scalac/atree/AShiftOp.java deleted file mode 100644 index 791ce54328..0000000000 --- a/sources/scalac/atree/AShiftOp.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a shift operation. */ -public class AShiftOp { - - //######################################################################## - // Public Cases - - /** A logical shift to the left */ - public case LSL; - - /** An arithmetic shift to the right */ - public case ASR; - - /** A logical shift to the right */ - public case LSR; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case LSL: return "LSL"; - case ASR: return "ASR"; - case LSR: return "LSR"; - default: throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATestOp.java b/sources/scalac/atree/ATestOp.java deleted file mode 100644 index 1d90f5ba0e..0000000000 --- a/sources/scalac/atree/ATestOp.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a test operation. */ -public class ATestOp { - - //######################################################################## - // Public Cases - - /** An equality test */ - public case EQ; - - /** A non-equality test */ - public case NE; - - /** A less-than test */ - public case LT; - - /** A greater-than-or-equal test */ - public case GE; - - /** A less-than-or-equal test */ - public case LE; - - /** A greater-than test */ - public case GT; - - //######################################################################## - // Public Methods - - /** Returns the negation of this operation. */ - public ATestOp negate() { - switch (this) { - case EQ: return NE; - case NE: return EQ; - case LT: return GE; - case GE: return LT; - case LE: return GT; - case GT: return LE; - default: throw Debug.abort("unknown case", this); - } - } - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case EQ: return "EQ"; - case NE: return "NE"; - case LT: return "LT"; - case GE: return "GE"; - case LE: return "LE"; - case GT: return "GT"; - default: throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATreeFactory.java b/sources/scalac/atree/ATreeFactory.java deleted file mode 100644 index 0c09650a16..0000000000 --- a/sources/scalac/atree/ATreeFactory.java +++ /dev/null @@ -1,531 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.ast.Tree; -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** This class implements an attributed tree factory. */ -public class ATreeFactory { - - //######################################################################## - // Public Fields - - /** The unique Void node */ - public final ACode Void = ACode.Void; - - /** The unique UNIT constant */ - public final AConstant UNIT = AConstant.UNIT; - - /** The unique NULL constant */ - public final AConstant NULL = AConstant.NULL; - - /** The unique ZERO constant */ - public final AConstant ZERO = AConstant.ZERO; - - //######################################################################## - // Public Methods - Building code - - /** Builds a This node. */ - public ACode This(Tree t, Symbol clasz) { - ACode.This code = ACode.This(clasz); - code.pos = t.pos; - return code; - } - - /** Builds a Constant node. */ - public ACode Constant(Tree t, AConstant constant) { - ACode.Constant code = ACode.Constant(constant); - code.pos = t.pos; - return code; - } - - /** Builds a Load node. */ - public ACode Load(Tree t, ALocation location) { - ACode.Load code = ACode.Load(location); - code.pos = t.pos; - return code; - } - - /** Builds a Store node. */ - public ACode Store(Tree t, ALocation location, ACode value) { - ACode.Store code = ACode.Store(location, value); - code.pos = t.pos; - return code; - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, AFunction function, Type[] ts, ACode[] vs) { - ACode.Apply code = ACode.Apply(function, ts, vs); - code.pos = t.pos; - return code; - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, AFunction function, Type[] ts) { - return Apply(t, function, ts, ACode.EMPTY_ARRAY); - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, AFunction function, ACode[] vs) { - return Apply(t, function, Type.EMPTY_ARRAY, vs); - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, AFunction function) { - return Apply(t, function, Type.EMPTY_ARRAY, ACode.EMPTY_ARRAY); - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, APrimitive primitive, ACode v0) { - return Apply(t, AFunction.Primitive(primitive), new ACode[] {v0}); - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, APrimitive primitive, ACode v0, ACode v1) { - return Apply(t, AFunction.Primitive(primitive), new ACode[] {v0,v1}); - } - - /** Builds an IsAs node. */ - public ACode IsAs(Tree t, ACode value, Type type, boolean cast) { - ACode.IsAs code = ACode.IsAs(value, type, cast); - code.pos = t.pos; - return code; - } - - /** Builds an If node. */ - public ACode If(Tree t, ACode test, ACode success, ACode failure) { - ACode.If code = ACode.If(test, success, failure); - code.pos = t.pos; - return code; - } - - /** Builds a Switch node. */ - public ACode Switch(Tree t, ACode test, int[][] tags, ACode[] bodies) { - ACode.Switch code = ACode.Switch(test, tags, bodies); - code.pos = t.pos; - return code; - } - - /** Builds a Synchronized node. */ - public ACode Synchronized(Tree t, ACode lock, ACode value) { - ACode.Synchronized code = ACode.Synchronized(lock, value); - code.pos = t.pos; - return code; - } - - /** Builds a Block node. */ - public ACode Block(Tree t, Symbol[] locals,ACode[] statements,ACode value){ - ACode.Block code = ACode.Block(locals, statements, value); - code.pos = t.pos; - return code; - } - - /** Builds a Label node. */ - public ACode Label(Tree t, Symbol label, Symbol[] locals, ACode value) { - ACode.Label code = ACode.Label(label, locals, value); - code.pos = t.pos; - return code; - } - - /** Builds a Goto node. */ - public ACode Goto(Tree t, Symbol label, ACode[] vargs) { - ACode.Goto code = ACode.Goto(label, vargs); - code.pos = t.pos; - return code; - } - - /** Builds a Return node. */ - public ACode Return(Tree t, Symbol function, ACode value) { - ACode.Return code = ACode.Return(function, value); - code.pos = t.pos; - return code; - } - - /** Builds a Throw node. */ - public ACode Throw(Tree t, ACode value) { - ACode.Throw code = ACode.Throw(value); - code.pos = t.pos; - return code; - } - - /** Builds a Drop node. */ - public ACode Drop(Tree t, ACode value, Type type) { - ACode.Drop code = ACode.Drop(value, type); - code.pos = t.pos; - return code; - } - - //######################################################################## - // Public Methods - Building primitive operations - - /** Builds a negation operation */ - public ACode NOT(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, NOT(kind), v0); - } - - /** Builds an EQ operation */ - public ACode EQ(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, EQ(kind, true), v0); - } - - /** Builds a NE operation */ - public ACode NE(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, NE(kind, true), v0); - } - - /** Builds a LT operation */ - public ACode LT(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, LT(kind, true), v0); - } - - /** Builds a GE operation */ - public ACode GE(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, GE(kind, true), v0); - } - - /** Builds a LE operation */ - public ACode LE(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, LE(kind, true), v0); - } - - /** Builds a GT operation */ - public ACode GT(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, GT(kind, true), v0); - } - - /** Builds an EQ operation */ - public ACode EQ(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, EQ(kind, false), v0, v1); - } - - /** Builds a NE operation */ - public ACode NE(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, NE(kind, false), v0, v1); - } - - /** Builds a LT operation */ - public ACode LT(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, LT(kind, false), v0, v1); - } - - /** Builds a GE operation */ - public ACode GE(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, GE(kind, false), v0, v1); - } - - /** Builds a LE operation */ - public ACode LE(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, LE(kind, false), v0, v1); - } - - /** Builds a GT operation */ - public ACode GT(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, GT(kind, false), v0, v1); - } - - /** Builds a CMPL operation */ - public ACode CMPL(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, CMPL(kind), v0, v1); - } - - /** Builds a CMP operation */ - public ACode CMP(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, CMP(kind), v0, v1); - } - - /** Builds a CMPG operation */ - public ACode CMPG(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, CMPG(kind), v0, v1); - } - - /** Builds an ADD operation */ - public ACode ADD(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, ADD(kind), v0, v1); - } - - /** Builds a SUB operation */ - public ACode SUB(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, SUB(kind), v0, v1); - } - - /** Builds a MUL operation */ - public ACode MUL(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, MUL(kind), v0, v1); - } - - /** Builds a DIV operation */ - public ACode DIV(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, DIV(kind), v0, v1); - } - - /** Builds a REM operation */ - public ACode REM(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, REM(kind), v0, v1); - } - - /** Builds an AND operation. */ - public ACode AND(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, AND(kind), v0, v1); - } - - /** Builds an OR operation. */ - public ACode OR(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, OR(kind), v0, v1); - } - - /** Builds an XOR operation. */ - public ACode XOR(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, XOR(kind), v0, v1); - } - - /** Builds a LSL operation. */ - public ACode LSL(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, LSL(kind), v0, v1); - } - - /** Builds a LSR operation. */ - public ACode LSR(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, LSR(kind), v0, v1); - } - - /** Builds an ASR operation. */ - public ACode ASR(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, ASR(kind), v0, v1); - } - - /** Builds a value conversion operation. */ - public ACode CONVERT(Tree t, ATypeKind src, ATypeKind dst, ACode v0) { - return Apply(t, CONVERT(src, dst), v0); - } - - /** Builds an array length operation. */ - public ACode LENGTH(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, LENGTH(kind), v0); - } - - /** Builds a string concatenation operation. */ - public ACode CONCAT(Tree t, ATypeKind lf, ATypeKind rg, ACode v0,ACode v1){ - return Apply(t, CONCAT(lf, rg), v0, v1); - } - - //######################################################################## - // Public Methods - Building primitives - - /** Builds a negation primitive */ - public APrimitive NOT(ATypeKind kind) { - return APrimitive.Negation(kind); - } - - /** Builds an EQ primitive */ - public APrimitive EQ(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.EQ, kind, zero); - } - - /** Builds a NE primitive */ - public APrimitive NE(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.NE, kind, zero); - } - - /** Builds a LT primitive */ - public APrimitive LT(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.LT, kind, zero); - } - - /** Builds a GE primitive */ - public APrimitive GE(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.GE, kind, zero); - } - - /** Builds a LE primitive */ - public APrimitive LE(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.LE, kind, zero); - } - - /** Builds a GT primitive */ - public APrimitive GT(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.GT, kind, zero); - } - - /** Builds a CMPL primitive */ - public APrimitive CMPL(ATypeKind kind) { - return APrimitive.Comparison(AComparisonOp.CMPL, kind); - } - - /** Builds a CMP primitive */ - public APrimitive CMP(ATypeKind kind) { - return APrimitive.Comparison(AComparisonOp.CMP, kind); - } - - /** Builds a CMPG primitive */ - public APrimitive CMPG(ATypeKind kind) { - return APrimitive.Comparison(AComparisonOp.CMPG, kind); - } - - /** Builds an ADD primitive */ - public APrimitive ADD(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.ADD, kind); - } - - /** Builds a SUB primitive */ - public APrimitive SUB(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.SUB, kind); - } - - /** Builds a MUL primitive */ - public APrimitive MUL(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.MUL, kind); - } - - /** Builds a DIV primitive */ - public APrimitive DIV(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.DIV, kind); - } - - /** Builds a REM primitive */ - public APrimitive REM(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.REM, kind); - } - - /** Builds an AND primitive. */ - public APrimitive AND(ATypeKind kind) { - return APrimitive.Logical(ALogicalOp.AND, kind); - } - - /** Builds an OR primitive. */ - public APrimitive OR(ATypeKind kind) { - return APrimitive.Logical(ALogicalOp.OR, kind); - } - - /** Builds an XOR primitive. */ - public APrimitive XOR(ATypeKind kind) { - return APrimitive.Logical(ALogicalOp.XOR, kind); - } - - /** Builds a LSL primitive. */ - public APrimitive LSL(ATypeKind kind) { - return APrimitive.Shift(AShiftOp.LSL, kind); - } - - /** Builds a LSR primitive. */ - public APrimitive LSR(ATypeKind kind) { - return APrimitive.Shift(AShiftOp.LSR, kind); - } - - /** Builds an ASR primitive. */ - public APrimitive ASR(ATypeKind kind) { - return APrimitive.Shift(AShiftOp.ASR, kind); - } - - /** Builds a value conversion primitive. */ - public APrimitive CONVERT(ATypeKind src, ATypeKind dst) { - return APrimitive.Conversion(src, dst); - } - - /** Builds an array length primitive. */ - public APrimitive LENGTH(ATypeKind kind) { - return APrimitive.ArrayLength(kind); - } - - /** Builds a string concatenation primitive. */ - public APrimitive CONCAT(ATypeKind lf, ATypeKind rg) { - return APrimitive.StringConcat(lf, rg); - } - - //######################################################################## - // Public Methods - Building constants - - /** Builds a BOOLEAN constant of given value. */ - public AConstant BOOLEAN(Boolean value) { - return BOOLEAN(value.booleanValue()); - } - - /** Builds a BOOLEAN constant of given value. */ - public AConstant BOOLEAN(boolean value) { - return AConstant.BOOLEAN(value); - } - - /** Builds a BYTE constant of given value. */ - public AConstant BYTE(Byte value) { - return BYTE(value.byteValue()); - } - - /** Builds a BYTE constant of given value. */ - public AConstant BYTE(byte value) { - return AConstant.BYTE(value); - } - - /** Builds a SHORT constant of given value. */ - public AConstant SHORT(Short value) { - return SHORT(value.shortValue()); - } - - /** Builds a SHORT constant of given value. */ - public AConstant SHORT(short value) { - return AConstant.SHORT(value); - } - - /** Builds a CHAR constant of given value. */ - public AConstant CHAR(Character value) { - return CHAR(value.charValue()); - } - - /** Builds a CHAR constant of given value. */ - public AConstant CHAR(char value) { - return AConstant.CHAR(value); - } - - /** Builds an INT constant of given value. */ - public AConstant INT(Integer value) { - return INT(value.intValue()); - } - - /** Builds an INT constant of given value. */ - public AConstant INT(int value) { - return AConstant.INT(value); - } - - /** Builds a LONG constant of given value. */ - public AConstant LONG(Long value) { - return LONG(value.longValue()); - } - - /** Builds a LONG constant of given value. */ - public AConstant LONG(long value) { - return AConstant.LONG(value); - } - - /** Builds a FLOAT constant of given value. */ - public AConstant FLOAT(Float value) { - return FLOAT(value.floatValue()); - } - - /** Builds a FLOAT constant of given value. */ - public AConstant FLOAT(float value) { - return AConstant.FLOAT(value); - } - - /** Builds a DOUBLE constant of given value. */ - public AConstant DOUBLE(Double value) { - return DOUBLE(value.doubleValue()); - } - - /** Builds a DOUBLE constant of given value. */ - public AConstant DOUBLE(double value) { - return AConstant.DOUBLE(value); - } - - /** Builds a STRING constant of given value. */ - public AConstant STRING(String value) { - return AConstant.STRING(value); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATreeFromSTree.java b/sources/scalac/atree/ATreeFromSTree.java deleted file mode 100644 index 83e50eb7e1..0000000000 --- a/sources/scalac/atree/ATreeFromSTree.java +++ /dev/null @@ -1,553 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; - -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.Ident; -import scalac.ast.Tree.Template; -import scalac.symtab.Definitions; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Name; - -/** This class translates syntax trees into attributed trees. */ -public class ATreeFromSTree { - - //######################################################################## - // Private Fields - - /** The global definitions */ - private final Definitions definitions; - - /** The attributed tree factory */ - private final ATreeFactory make; - - /** A mapping from primitive classes to initialization state */ - private final Map/*<Symbol,Boolean>*/ states; - - /** A mapping from primitive methods to generators */ - private final Map/*<Symbol,Generator>*/ generators; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ATreeFromSTree(Definitions definitions) { - this.definitions = definitions; - this.make = new ATreeFactory(); - this.states = new HashMap(); - this.generators = new HashMap(); - Symbol[] classes = { - definitions.ANY_CLASS, - definitions.OBJECT_CLASS, - definitions.STRING_CLASS, - definitions.THROWABLE_CLASS, - definitions.ARRAY_CLASS, - definitions.UNIT_CLASS, - definitions.BOOLEAN_CLASS, - definitions.BYTE_CLASS, - definitions.SHORT_CLASS, - definitions.CHAR_CLASS, - definitions.INT_CLASS, - definitions.LONG_CLASS, - definitions.FLOAT_CLASS, - definitions.DOUBLE_CLASS, - }; - for (int i = 0; i < classes.length; i++) - states.put(classes[i], Boolean.FALSE); - } - - //######################################################################## - // Public Methods - Translating units - - /** Translates the unit's body and stores the result in it. */ - public void translate(CompilationUnit unit) { - template(unit.repository = new ARepository(), unit.body); - } - - //######################################################################## - // Private Methods - Translating templates - - /** Translates the templates and adds them to the repository. */ - private void template(ARepository repository, Tree[] trees) { - for (int i = 0; i < trees.length; i++) template(repository, trees[i]); - } - - /** Translates the template and adds it to the repository. */ - private void template(ARepository repository, Tree tree) { - switch (tree) { - - case Empty: - return; - - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - AClass clasz = new AClass(tree.symbol()); - // !!! add static field to global modules - repository.addClass(clasz); - member(clasz, body); - return; - - case PackageDef(_, Template(_, Tree[] body)): - template(repository, body); - return; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Translating members - - /** Translates the members and adds them to the class. */ - private void member(AClass clasz, Tree[] trees) { - for (int i = 0; i < trees.length; i++) member(clasz, trees[i]); - } - - /** Translates the member and adds it to the class. */ - private void member(AClass clasz, Tree tree) { - switch (tree) { - - case Empty: - return; - - case ClassDef(_, _, _, _, _, _): - template(clasz, tree); - return; - - case ValDef(_, _, _, Tree rhs): - AField field = new AField(tree.symbol(), false); - clasz.addField(field); - return; - - case DefDef(_, _, _, _, _, Tree rhs): - AMethod method = new AMethod(tree.symbol(), false); - clasz.addMethod(method); - if (!method.isAbstract()) method.setCode(expression(rhs)); - return; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Translating statements - - /** Translates the statements. */ - private ACode[] statement(List locals, Tree[] trees) { - List codes = new ArrayList(); - for (int i = 0; i < trees.length; i++) { - ACode code = statement(locals, trees[i]); - if (code != ACode.Void) codes.add(code); - } - return (ACode[])codes.toArray(new ACode[codes.size()]); - } - - /** Translates the statement. */ - private ACode statement(List locals, Tree tree) { - switch (tree) { - - case Empty: - return make.Void; - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = tree.symbol(); - locals.add(symbol); - ALocation location = ALocation.Local(symbol, false); - return make.Store(tree, location, expression(rhs)); - - default: - return ACode.Drop(expression(tree), tree.type()); - } - } - - //######################################################################## - // Private Methods - Translating expressions - - /** Translates the expressions. */ - private ACode[] expression(Tree[] trees) { - ACode[] codes = new ACode[trees.length]; - for (int i = 0; i < codes.length; i++) codes[i] = expression(trees[i]); - return codes; - } - - /** Translates the expression. */ - private ACode expression(Tree tree) { - switch (tree) { - - case LabelDef(_, Ident[] idents, Tree rhs): - Symbol[] locals = Tree.symbolOf(idents); - return make.Label(tree, tree.symbol(), locals, expression(rhs)); - - case Block(Tree[] stats, Tree value): - List locals = new ArrayList(); - ACode[] codes = statement(locals, stats); - ACode code = expression(value); - if (locals.size() == 0 && codes.length == 0) return code; - Symbol[] symbols = - (Symbol[])locals.toArray(new Symbol[locals.size()]); - return make.Block(tree, symbols, codes, code); - - case Assign(Tree lhs, Tree rhs): - return make.Block(tree, Symbol.EMPTY_ARRAY, new ACode[] { - make.Store(tree, location(lhs), expression(rhs))}, - make.Void); - - case If(Tree cond, Tree thenp, Tree elsep): - ACode test = expression(cond); - return make.If(tree, test, expression(thenp), expression(elsep)); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - int[][] tagss = new int[tags.length][]; - for (int i = 0; i < tagss.length; i++) - tagss[i] = new int[] {tags[i]}; - ACode[] codes = new ACode[bodies.length + 1]; - for (int i = 0; i < bodies.length; i++) - codes[i] = expression(bodies[i]); - codes[tags.length] = expression(otherwise); - return make.Switch(tree, expression(test), tagss, codes); - - case Return(Tree value): - return make.Return(tree, tree.symbol(), expression(value)); - - case Throw(Tree value): - return make.Throw(tree, expression(value)); - - case New(Apply(Tree fun, Tree[] vargs)): - switch (fun) { - case Select(Create(_, Tree[] targs), _): - return apply(tree, fun, targs, vargs); - default: - throw Debug.abort("illegal case", tree); - } - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - return apply(tree, fun, targs, vargs); - case Apply(Tree fun, Tree[] vargs): - return apply(tree, fun, Tree.EMPTY_ARRAY, vargs); - - case Super(_, _): - case This(_): - return make.This(tree, tree.symbol()); - - case Select(_, _): - case Ident(_): - return make.Load(tree, location(tree)); - - case Literal(AConstant value): - return make.Constant(tree, value); - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Translates the application. */ - private ACode apply(Tree tree, Tree fun, Tree[] targs, Tree[] vargs) { - Symbol symbol = fun.symbol(); - ACode[] codes = expression(vargs); - if (symbol.isLabel()) return make.Goto(tree, symbol, codes); - Type[] types = Tree.typeOf(targs); - AFunction function = function(fun); - switch (function) { - case Method(ACode object, Symbol method, AInvokeStyle style): - if (!style.isDynamic()) break; - Symbol clasz = method.owner(); - Object state = states.get(clasz); - if (state == null) break; - if (state != Boolean.TRUE) addGeneratorsOf(clasz); - Object generator = generators.get(method); - if (generator == null) break; - return generate((Generator)generator, tree, object, types, vargs); - } - return make.Apply(tree, function, types, codes); - } - - //######################################################################## - // Private Methods - Translating functions - - /** Translates the method. */ - private AFunction function(Tree tree) { - Symbol symbol = tree.symbol(); - switch (tree) { - - case Select(Create(_, _), _): - AInvokeStyle style = AInvokeStyle.New; - return AFunction.Method(make.Void, symbol, style); - - case Select(Tree qualifier, _): - AInvokeStyle style = invokeStyle(qualifier); - return AFunction.Method(expression(qualifier), symbol, style); - - case Ident(_): - AInvokeStyle style = AInvokeStyle.StaticClass; - return AFunction.Method(make.Void, symbol, style); - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Returns the InvokeStyle to use for the qualifier. */ - private AInvokeStyle invokeStyle(Tree qualifier) { - switch (qualifier) { - case Super(_, _): - return AInvokeStyle.StaticInstance; - default: - return AInvokeStyle.Dynamic; - } - } - - //######################################################################## - // Private Methods - Translating locations - - /** Translates the location. */ - private ALocation location(Tree tree) { - Symbol symbol = tree.symbol(); - switch (tree) { - - case Select(Tree qualifier, _): - return ALocation.Field(expression(qualifier), symbol, false); - - case Ident(_): - if (symbol.isModule()) return ALocation.Module(symbol); - return symbol.owner().isClass() - ? ALocation.Field(make.Void, symbol, true) - : ALocation.Local(symbol, symbol.isParameter()); - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Translating constants - - /** Translates the constant. */ - private AConstant constant(Object value) { - if (value instanceof Boolean ) return make.BOOLEAN((Boolean )value); - if (value instanceof Byte ) return make.BYTE (((Byte )value)); - if (value instanceof Short ) return make.SHORT ((Short )value); - if (value instanceof Character) return make.CHAR ((Character)value); - if (value instanceof Integer ) return make.INT ((Integer )value); - if (value instanceof Long ) return make.LONG ((Long )value); - if (value instanceof Float ) return make.FLOAT ((Float )value); - if (value instanceof Double ) return make.DOUBLE ((Double )value); - if (value instanceof String ) return make.STRING ((String )value); - throw Debug.abort("illegal constant", value +" -- "+ value.getClass()); - } - - //######################################################################## - // Private Methods - Generating code for primitive methods - - /** Applies generator to given object and arguments. */ - private ACode generate(Generator generator, Tree tree, ACode object, - Type[] targs, Tree[] vargs) - { - switch (generator) { - - case ANYID: - assert targs.length == 0 && vargs.length == 1: tree; - return make.EQ(tree, ATypeKind.REF, object, expression(vargs[0])); - - case ANYNI: - assert targs.length == 0 && vargs.length == 1: tree; - return make.NE(tree, ATypeKind.REF, object, expression(vargs[0])); - - case ANYEQ: - Symbol lf = newLocal(tree, definitions.ANY_TYPE()); - Symbol rg = newLocal(tree, definitions.ANY_TYPE()); - return make.Block(tree, - new Symbol[] {lf, rg}, - new ACode[] { - store(tree, lf, object), - store(tree, rg, expression(vargs[0]))}, - make.If(tree, - make.EQ(tree, ATypeKind.REF, load(tree, lf)), - make.EQ(tree, ATypeKind.REF, load(tree, rg)), - make.Apply(tree, - AFunction.Method( - load(tree, lf), - definitions.ANY_EQUALS, - AInvokeStyle.Dynamic), - Type.EMPTY_ARRAY, - new ACode[] {load(tree, rg)}))); - - case ANYNE: - Symbol lf = newLocal(tree, definitions.ANY_TYPE()); - Symbol rg = newLocal(tree, definitions.ANY_TYPE()); - return make.Block(tree, - new Symbol[] {lf, rg}, - new ACode[] { - store(tree, lf, object), - store(tree, rg, expression(vargs[0]))}, - make.If(tree, - make.EQ(tree, ATypeKind.REF, load(tree, lf)), - make.NE(tree, ATypeKind.REF, load(tree, rg)), - make.NOT(tree, - ATypeKind.BOOL, - make.Apply(tree, - AFunction.Method( - load(tree, lf), - definitions.ANY_EQUALS, - AInvokeStyle.Dynamic), - Type.EMPTY_ARRAY, - new ACode[] {load(tree, rg)})))); - - case ISAS(boolean cast): - assert targs.length == 1 && vargs.length == 0: tree; - return make.IsAs(tree, object, targs[0], cast); - - case SYNCHRONIZED: - assert targs.length == 1 && vargs.length == 1: tree; - return make.Synchronized(tree, object, expression(vargs[0])); - - case THROW: - assert targs.length == 0 && vargs.length == 0: tree; - return make.Throw(tree, object); - - case CONCAT(ATypeKind prefix): - assert targs.length == 0 && vargs.length == 1: tree; - ATypeKind suffix = kind(vargs[0].type()); - ACode argument = expression(vargs[0]); - return make.CONCAT(tree, prefix, suffix, object, argument); - - default: - throw Debug.abort("unknown case", generator); - } - } - - /** Generates a load operation with given variable. */ - private ACode load(Tree tree, Symbol local) { - assert local.owner().isNone(): Debug.show(local); - return make.Load(tree, ALocation.Local(local, false)); - } - - /** Generates a store operation with given variable and value. */ - private ACode store(Tree tree, Symbol local, ACode value) { - assert local.owner().isNone(): Debug.show(local); - return make.Store(tree, ALocation.Local(local, false), value); - } - - /** Creates a variable with tree's position and given type. */ - private Symbol newLocal(Tree tree, Type type) { - Symbol owner = Symbol.NONE; // !!! - Name name = Name.fromString("local"); // !!! - return owner.newTerm(tree.pos, 0, name).setType(type); - } - - /** Returns the type kind of given type. */ - private ATypeKind kind(Type type) { - switch (type) { - case SingleType(_, _): - case ConstantType(_, _): - return kind(type.singleDeref()); - case TypeRef(_, Symbol clasz, _): - if (clasz == definitions.BOOLEAN_CLASS) return ATypeKind.BOOL; - if (clasz == definitions.BYTE_CLASS) return ATypeKind.I1; - if (clasz == definitions.SHORT_CLASS) return ATypeKind.I2; - if (clasz == definitions.CHAR_CLASS) return ATypeKind.U2; - if (clasz == definitions.INT_CLASS) return ATypeKind.I4; - if (clasz == definitions.LONG_CLASS) return ATypeKind.I8; - if (clasz == definitions.FLOAT_CLASS) return ATypeKind.R4; - if (clasz == definitions.DOUBLE_CLASS) return ATypeKind.R8; - if (clasz == definitions.STRING_CLASS) return ATypeKind.STR; - return ATypeKind.REF; - default: - return ATypeKind.REF; - } - } - - //######################################################################## - // Private Methods - Collecting primitive methods - - /** Associates generators to primitive methods of given class. */ - private void addGeneratorsOf(Symbol clasz) { - if (clasz == definitions.ANY_CLASS) { - addGenerator(definitions.ANY_EQEQ, Generator.ANYEQ); - addGenerator(definitions.ANY_BANGEQ, Generator.ANYNE); - addGenerator(definitions.ANY_IS_ERASED, Generator.ISAS(false)); - addGenerator(definitions.ANY_AS_ERASED, Generator.ISAS(true)); - } - if (clasz == definitions.OBJECT_CLASS) { - addGenerator(definitions.OBJECT_EQ, Generator.ANYID); - addGenerator(definitions.OBJECT_NE, Generator.ANYNI); - addGenerator(definitions.OBJECT_SYNCHRONIZED, Generator.SYNCHRONIZED); - } - if (clasz == definitions.STRING_CLASS) { - addGenerator(definitions.STRING_PLUS, Generator.CONCAT(ATypeKind.STR)); - } - if (clasz == definitions.THROWABLE_CLASS) { - addGenerator(definitions.THROWABLE_THROW, Generator.THROW); - } - if (clasz == definitions.ARRAY_CLASS) { - // !!! addAll(defs.ARRAY_CLASS, Names.length, Primitive.LENGTH, 1); - // !!! addAll(defs.ARRAY_CLASS, Names.apply, Primitive.APPLY, 2); - // !!! addAll(defs.ARRAY_CLASS, Names.update, Primitive.UPDATE, 1); - } - if (clasz == definitions.UNIT_CLASS) { - // !!! - } - if (clasz == definitions.BOOLEAN_CLASS) { - // !!! - } - if (clasz == definitions.BYTE_CLASS) { - // !!! - } - if (clasz == definitions.SHORT_CLASS) { - // !!! - } - if (clasz == definitions.CHAR_CLASS) { - // !!! - } - if (clasz == definitions.INT_CLASS) { - // !!! - } - if (clasz == definitions.LONG_CLASS) { - // !!! - } - if (clasz == definitions.FLOAT_CLASS) { - // !!! - } - if (clasz == definitions.DOUBLE_CLASS) { - // !!! - } - states.put(clasz, Boolean.TRUE); - } - - /** Associates given generator to given primitive method. */ - private void addGenerator(Symbol method, Generator generator) { - generators.put(method, generator); - } - - //######################################################################## - // Private Class - Code generators - - /** Code generators for primitive methods. */ - private static class Generator { - case ANYID; - case ANYNI; - case ANYEQ; - case ANYNE; - case ISAS(boolean cast); - case SYNCHRONIZED; - case THROW; - case CONCAT(ATypeKind prefix); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATreePrinter.java b/sources/scalac/atree/ATreePrinter.java deleted file mode 100644 index fb0a108a99..0000000000 --- a/sources/scalac/atree/ATreePrinter.java +++ /dev/null @@ -1,557 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import ch.epfl.lamp.util.CodePrinter; - -import scalac.Global; -import scalac.Phase; -import scalac.CompilationUnit; -import scalac.symtab.Type; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolTablePrinter; -import scalac.util.Debug; -import scalac.util.SourceRepresentation; - -/** This class provides methods to print attributed trees. */ -public class ATreePrinter { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The underlying code printer */ - private final CodePrinter printer; - - /** The underlying symbol table printer */ - private final SymbolTablePrinter symtab; - - //######################################################################## - // Public Constructors - - /** Initalizes this instance */ - public ATreePrinter() { - this(new CodePrinter()); - } - - /** Initalizes this instance */ - public ATreePrinter(String step) { - this(Global.instance, new CodePrinter(step)); - } - - /** Initalizes this instance */ - public ATreePrinter(CodePrinter printer) { - this(Global.instance, printer); - } - - /** Initalizes this instance */ - public ATreePrinter(Global global, CodePrinter printer) { - this.global = global; - this.printer = printer; - this.symtab = new SymbolTablePrinter(global, printer); - } - - //######################################################################## - // Public Methods - Getting & Setting - - /** Returns the underlying code printer. */ - public CodePrinter getCodePrinter() { - return printer; - } - - //######################################################################## - // Public Methods - Formatting - - /** Increases the indentation level by one. */ - public ATreePrinter indent() { - printer.indent(); - return this; - } - - /** Decreases the indentation level by one. */ - public ATreePrinter undent() { - printer.undent(); - return this; - } - - /** Inserts a new line. */ - public ATreePrinter line() { - printer.line(); - return this; - } - - /** Inserts a white space. */ - public ATreePrinter space() { - printer.space(); - return this; - } - - /** Prints an opening brace followed by a new line. */ - public ATreePrinter lbrace() { - return space().println('{').indent(); - } - - /** Prints a closing brace followed by a new line. */ - public ATreePrinter rbrace() { - return undent().space().println('}'); - } - - //######################################################################## - // Public Methods - Printing simple values - - /** Prints a new line. */ - public ATreePrinter println() { - printer.println(); - return this; - } - - /** Prints the boolean value followed by a new line. */ - public ATreePrinter println(boolean value) { - printer.println(value); - return this; - } - - /** Prints the byte value followed by a new line. */ - public ATreePrinter println(byte value) { - printer.println(value); - return this; - } - - /** Prints the short value followed by a new line. */ - public ATreePrinter println(short value) { - printer.println(value); - return this; - } - - /** Prints the char value followed by a new line. */ - public ATreePrinter println(char value) { - printer.println(value); - return this; - } - - /** Prints the int value followed by a new line. */ - public ATreePrinter println(int value) { - printer.println(value); - return this; - } - - /** Prints the long value followed by a new line. */ - public ATreePrinter println(long value) { - printer.println(value); - return this; - } - - /** Prints the float value followed by a new line. */ - public ATreePrinter println(float value) { - printer.println(value); - return this; - } - - /** Prints the double value followed by a new line. */ - public ATreePrinter println(double value) { - printer.println(value); - return this; - } - - /** Prints the string followed by a new line. */ - public ATreePrinter println(String value) { - printer.println(value); - return this; - } - - /** Prints the boolean value. */ - public ATreePrinter print(boolean value) { - printer.print(value); - return this; - } - - /** Prints the byte value. */ - public ATreePrinter print(byte value) { - printer.print(value); - return this; - } - - /** Prints the short value. */ - public ATreePrinter print(short value) { - printer.print(value); - return this; - } - - /** Prints the char value. */ - public ATreePrinter print(char value) { - printer.print(value); - return this; - } - - /** Prints the int value. */ - public ATreePrinter print(int value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public ATreePrinter print(long value) { - printer.print(value); - return this; - } - - /** Prints the float value. */ - public ATreePrinter print(float value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public ATreePrinter print(double value) { - printer.print(value); - return this; - } - - /** Prints the string. */ - public ATreePrinter print(String value) { - printer.print(value); - return this; - } - - //######################################################################## - // Public Methods - Printing types and symbols - - /** Prints the symbol. */ - public ATreePrinter printSymbol(Symbol symbol) { - symtab.printSymbolName(symbol); - return this; - } - - /** Prints the type. */ - public ATreePrinter printType(Type type) { - symtab.printType(type); - return this; - } - - //######################################################################## - // Public Methods - Printing trees - - /** Prints the units. */ - public ATreePrinter printUnits(CompilationUnit[] units) { - Phase phase = global.currentPhase; - println("[[attributed trees at "+phase+" (after "+phase.prev+")]]"); - for (int i = 0; i < units.length; i++) printUnit(units[i]); - return this; - } - - /** Prints the unit. */ - public ATreePrinter printUnit(CompilationUnit unit) { - println("// Scala source: " + unit.source); - return printRepository(unit.repository); - } - - /** Prints the repository. */ - public ATreePrinter printRepository(ARepository repository) { - AClass[] classes = repository.classes(); - for (int i = 0; i < classes.length; i++) printClass(classes[i]); - return this; - } - - /** Prints the class. */ - public ATreePrinter printClass(AClass clasz) { - printClassModifiers(clasz); - print(clasz.isInterface() ? "interface" : "class").space(); - printSymbol(clasz.symbol()); - Symbol[] tparams = clasz.tparams(); - if (tparams.length != 0) symtab.printTypeParams(tparams); - Symbol[] vparams = clasz.vparams(); - if (vparams.length != 0) symtab.printValueParams(vparams); - if (clasz.symbol().typeOfThis() != clasz.symbol().thisType()) - space().print(':').printType(clasz.symbol().typeOfThis()); - space().print("extends").space(); - symtab.printTypes(clasz.parents()," with "); - lbrace(); - printRepository(clasz); - AField[] fields = clasz.fields(); - for (int i = 0; i < fields.length; i++) printField(fields[i]); - AMethod[] methods = clasz.methods(); - for (int i = 0; i < methods.length; i++) printMethod(methods[i]); - return rbrace(); - } - - /** Prints the class modifiers. */ - public ATreePrinter printClassModifiers(AClass clasz) { - if (clasz.isDeprecated()) print("deprecated").space(); - if (clasz.isSynthetic()) print("synthetic").space(); - if (clasz.isPublic()) print("public").space(); - if (clasz.isPrivate()) print("private").space(); - if (clasz.isProtected()) print("protected").space(); - if (clasz.isFinal()) print("final").space(); - if (clasz.isAbstract()) print("abstract").space(); - return this; - } - - /** Prints the member modifiers. */ - public ATreePrinter printMemberModifiers(AMember member) { - if (member.isDeprecated()) print("deprecated").space(); - if (member.isSynthetic()) print("synthetic").space(); - if (member.isPublic()) print("public").space(); - if (member.isPrivate()) print("private").space(); - if (member.isProtected()) print("protected").space(); - if (member.isStatic()) print("static").space(); - return this; - } - - /** Prints the member code. */ - public ATreePrinter printMemberCode(AMember member) { - if (member.code() == ACode.Void) return this; - return print('=').space().printCode(member.code()); - } - - /** Prints the field. */ - public ATreePrinter printField(AField field) { - printFieldModifiers(field); - symtab.printSignature(field.symbol()).space(); - return printMemberCode(field).line(); - } - - /** Prints the field modifiers. */ - public ATreePrinter printFieldModifiers(AField field) { - printMemberModifiers(field); - if (field.isFinal()) print("final").space(); - if (field.isVolatile()) print("volatile").space(); - if (field.isTransient()) print("transient").space(); - return this; - } - - /** Prints the method. */ - public ATreePrinter printMethod(AMethod method) { - printMethodModifiers(method); - symtab.printSignature(method.symbol()).space(); - return printMemberCode(method).line(); - } - - /** Prints the method modifiers. */ - public ATreePrinter printMethodModifiers(AMethod method) { - printMemberModifiers(method); - if (method.isFinal()) print("final").space(); - if (method.isSynchronized()) print("synchronized").space(); - if (method.isNative()) print("native").space(); - if (method.isAbstract()) print("abstract").space(); - return this; - } - - /** Prints the code. */ - public ATreePrinter printCode(ACode code) { - switch (code) { - case Void: - return print("<void>"); - case This(Symbol clasz): - return printSymbol(clasz).print('.').print("this"); - case Constant(AConstant constant): - return printConstant(constant); - case Load(ALocation location): - return printLocation(location); - case Store(ALocation location, ACode value): - printLocation(location).space().print('=').space(); - return printCode(value); - case Apply(AFunction function, Type[] targs, ACode[] vargs): - printFunction(function); - if (targs.length > 0){ - print('['); - for (int i = 0; i < targs.length; i++) - (i == 0 ? this : print(',').space()).printType(targs[i]); - print(']'); - } - print('('); - for (int i = 0; i < vargs.length; i++) - (i == 0 ? this : print(',').space()).printCode(vargs[i]); - print(')'); - return this; - case IsAs(ACode value, Type type, boolean cast): - printCode(value).print('.').print(cast ? "as" : "is"); - return print('[').printType(type).print(']'); - case If(ACode test, ACode success, ACode failure): - print("if").space().print('(').printCode(test).print(')').lbrace(); - printCode(success).line(); - rbrace().space().print("else").space().lbrace(); - printCode(failure).line(); - return rbrace(); - case Switch(ACode test, int[][] tags, ACode[] bodies): - print("switch").space().print('(').printCode(test).print(')'); - lbrace(); - for (int i = 0; i < tags.length; i++) { - for (int j = 0; j < tags[i].length; j++) - print("case").space().print(tags[i][j]).print(':').line(); - indent().printCode(bodies[i]).undent().line(); - } - print("case").space().print('_').print(':').line(); - indent().printCode(bodies[tags.length]).undent(); - return rbrace(); - case Synchronized(ACode lock, ACode value): - print("synchronized").space(); - print('(').printCode(lock).print(')'); - return lbrace().printCode(value).rbrace(); - case Block(Symbol[] locals, ACode[] statements, ACode value): - lbrace(); - for (int i = 0; i < locals.length; i++) { - print("var").space().printSymbol(locals[i]); - print(":").space().printType(locals[i].type()); - println(";"); - } - for (int i = 0; i < statements.length; i++) - printCode(statements[i]).println(';'); - return printCode(value).line().rbrace(); - case Label(Symbol label, Symbol[] locals, ACode value): - print("label").space().printSymbol(label).print('('); - for (int i = 0; i < locals.length; i++) - (i == 0 ? this : print(',').space()).printSymbol(locals[i]); - print(')').space().print('=').lbrace(); - return printCode(value).rbrace(); - case Goto(Symbol label, ACode[] vargs): - print("goto").space().printSymbol(label).print('('); - for (int i = 0; i < vargs.length; i++) - (i == 0 ? this : print(',').space()).printCode(vargs[i]); - return print(')'); - case Return(Symbol function, ACode value): - print("return").symtab.printSymbolUniqueId(function).space(); - return printCode(value); - case Throw(ACode value): - return print("throw").space().printCode(value); - case Drop(ACode value, Type type): - print("drop").print('[').printType(type).print(']').space(); - return printCode(value); - default: - throw Debug.abort("unknown case", code); - } - } - - /** Prints the location. */ - public ATreePrinter printLocation(ALocation location) { - switch (location) { - case Module(Symbol module): - return printSymbol(module); - case Field(Void, Symbol field, true): - return printSymbol(field.owner()).print('.').printSymbol(field); - case Field(ACode object, Symbol field, boolean isStatic): - printCode(object).print('.'); - if (isStatic) print("<static>").space(); - return printSymbol(field); - case Local(Symbol local, _): - return printSymbol(local); - case ArrayItem(ACode array, ACode index): - return printCode(array).print('(').printCode(index).print(')'); - default: - throw Debug.abort("unknown case", location); - } - } - - /** Prints the function. */ - public ATreePrinter printFunction(AFunction function) { - switch (function) { - case Method(Void, Symbol method, AInvokeStyle.New): - return print("new").space().printSymbol(method); - case Method(Void, Symbol method, AInvokeStyle.Static(false)): - return printSymbol(method.owner()).print('.').printSymbol(method); - case Method(This(Symbol c), Symbol method, AInvokeStyle.Static(true)): - printSymbol(c).print('.').print("super").print('.'); - return printSymbol(method); - case Method(ACode object, Symbol method, AInvokeStyle style): - printCode(object).print('.'); - if (style != AInvokeStyle.Dynamic) print("<" +style+ ">").space(); - return printSymbol(method); - case Primitive(APrimitive primitive): - return printPrimitive(primitive); - case NewArray(Type element): - return print("new").space().printType(element).print("[]"); - default: - throw Debug.abort("unknown case", function); - } - } - - /** Prints the primitive. */ - public ATreePrinter printPrimitive(APrimitive primitive) { - switch (primitive) { - case Negation(ATypeKind kind): - return printPrimitiveOp("NEG", kind); - case Test(ATestOp op, ATypeKind kind, boolean zero): - return printPrimitiveOp(op.toString() + (zero ? "Z" : ""), kind); - case Comparison(AComparisonOp op, ATypeKind kind): - return printPrimitiveOp(op.toString(), kind); - case Arithmetic(AArithmeticOp op, ATypeKind kind): - return printPrimitiveOp(op.toString(), kind); - case Logical(ALogicalOp op, ATypeKind kind): - return printPrimitiveOp(op.toString(), kind); - case Shift(AShiftOp op, ATypeKind kind): - return printPrimitiveOp(op.toString(), kind); - case Conversion(ATypeKind src, ATypeKind dst): - return printPrimitiveOp("CONV", src, dst); - case ArrayLength(ATypeKind kind): - return printPrimitiveOp("LENGTH", kind); - case StringConcat(ATypeKind lf, ATypeKind rg): - return printPrimitiveOp("CONCAT", lf, rg); - default: - throw Debug.abort("unknown case", primitive); - } - } - - /** Prints the primitive operation of given type kind. */ - public ATreePrinter printPrimitiveOp(String op, ATypeKind kind) { - return printPrimitiveOp(op, kind, null); - } - - /** Prints the primitive operation of given types. */ - public ATreePrinter printPrimitiveOp(String op, ATypeKind k1,ATypeKind k2){ - print('<').print(op).print('>'); - if (k1 != null && global.uniqid) print('#').print(k1.toString()); - if (k2 != null && global.uniqid) print(',').print(k2.toString()); - return this; - } - - /** Prints the constant. */ - public ATreePrinter printConstant(AConstant constant) { - switch (constant) { - case UNIT: - return print("()"); - case BOOLEAN(boolean value): - return print(value); - case BYTE(byte value): - return print(value); - case SHORT(short value): - return print(value); - case CHAR(char value): - return print('\'').print(value).print('\''); - case INT(int value): - return print(value); - case LONG(long value): - return print(value); - case FLOAT(float value): - return print(value); - case DOUBLE(double value): - return print(value); - case STRING(String value): - return print('\"').print(SourceRepresentation.escape(value)).print('\"'); - case SYMBOL_NAME(Symbol value): - return print('\"').print(SourceRepresentation.escape(value.name.toString())).print('\"'); - case NULL: - return print("null"); - case ZERO: - return print("<zero>"); - default: - throw Debug.abort("unknown case", constant); - } - } - - //######################################################################## - // Public Methods - Converting - - /** Returns the string representation of this printer. */ - public String toString() { - return printer.toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATreeTyper.java b/sources/scalac/atree/ATreeTyper.java deleted file mode 100644 index 06133db15f..0000000000 --- a/sources/scalac/atree/ATreeTyper.java +++ /dev/null @@ -1,314 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scala.tools.util.Position; - -import scalac.Global; -import scalac.symtab.Definitions; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Name; - -/** This class implements an attributed tree typer. */ -public class ATreeTyper { - - //######################################################################## - // Private Fields - - /** The global environment */ - public final Global global; - - /** The global definitions */ - private final Definitions definitions; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ATreeTyper(Global global, Definitions definitions) { - this.global = global; - this.definitions = definitions; - } - - //######################################################################## - // Public Methods - Typing code - - /** Returns the types of the given codes. */ - public Type[] type(ACode[] codes) { - Type[] types = new Type[codes.length]; - for (int i = 0; i < types.length; i++) types[i] = type(codes[i]); - return types; - } - - /** Returns the type of the given code. */ - public Type type(ACode code) { - switch (code) { - case Void: - return definitions.void_TYPE(); - case This(Symbol clasz): - return clasz.thisType(); - case Constant(AConstant constant): - return type(constant); - case Load(ALocation location): - return type(location); - case Store(_, _): - return Type.NoType; - case Apply(AFunction function, Type[] targs, _): - return apply(type(function), targs).resultType(); - case IsAs(_, Type type, boolean cast): - return cast ? type : definitions.boolean_TYPE(); - case If(_, ACode success, ACode failure): - return Type.lub(new Type[]{type(success), type(failure)}); - case Switch(_, _, ACode[] bodies): - return Type.lub(type(bodies)); - case Synchronized(_, ACode value): - return type(value); - case Block(_, _, ACode value): - return type(value); - case Label(Symbol label, _, _): - return label.type().resultType(); - case Goto(_, _): - return Type.NoType; - case Return(_, _): - return Type.NoType; - case Throw(_): - return Type.NoType; - case Drop(_, _): - return Type.NoType; - default: - throw Debug.abort("unknown case", code); - } - } - - //######################################################################## - // Public Methods - Typing value locations - - /** Returns the type of the given value location. */ - public Type type(ALocation location) { - switch (location) { - case Module(Symbol module): - return module.thisType(); - case Field(Void, Symbol field, _): - return field.owner().thisType().memberStabilizedType(field); - case Field(ACode object, Symbol field, _): - return type(object).memberStabilizedType(field); - case Local(Symbol local, _): - return local.type(); - case ArrayItem(ACode array, _): - return getArrayElementType(type(array)); - default: - throw Debug.abort("unknown case", location); - } - } - - //######################################################################## - // Public Methods - Typing function references - - /** Returns the type of the given function reference. */ - public Type type(AFunction function) { - switch (function) { - case Method(Void, Symbol method, AInvokeStyle style): - Type type = method.owner().thisType().memberStabilizedType(method); - if (style == AInvokeStyle.New) { - assert method.isInitializer(): function; - Symbol[] tparams = method.owner().typeParams(); - if (tparams.length != 0) type = Type.PolyType(tparams, type); - } - return type; - case Method(ACode object, Symbol method, _): - return type(object).memberStabilizedType(method); - case Primitive(APrimitive primitive): - return type(primitive); - case NewArray(Type element): - return definitions.array_TYPE(element); - default: - throw Debug.abort("unknown case", function); - } - } - - //######################################################################## - // Public Methods - Typing primitives - - /** Returns the type of the given primitive. */ - public Type type(APrimitive primitive) { - switch (primitive) { - case Negation(ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type); - case Test(_, ATypeKind kind, true): - Type type = type(kind); - return getMethodType(type, type(ATypeKind.BOOL)); - case Test(_, ATypeKind kind, false): - Type type = type(kind); - return getMethodType(type, type, type(ATypeKind.BOOL)); - case Comparison(_, ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type, type(ATypeKind.I4)); - case Arithmetic(_, ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type, type); - case Logical(_, ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type, type); - case Shift(_, ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type(ATypeKind.I4), type); - case Conversion(ATypeKind src, ATypeKind dst): - return getMethodType(type(src), type(dst)); - case ArrayLength(ATypeKind kind): - Type type = definitions.array_TYPE(type(kind)); - return getMethodType(type, type(ATypeKind.I4)); - case StringConcat(ATypeKind lf, ATypeKind rg): - return getMethodType(type(lf), type(rg), type(ATypeKind.STR)); - default: - throw Debug.abort("unknown case", primitive); - } - } - - //######################################################################## - // Public Methods - Typing constants - - /** Returns the type of the given constant. */ - public Type type(AConstant constant) { - Type base = basetype(constant); - if (global.currentPhase.id > global.PHASE.ERASURE.id()) return base; - return Type.ConstantType(base, constant); - } - - /** Returns the base type of the given constant. */ - public Type basetype(AConstant constant) { - switch (constant) { - case UNIT : return definitions.void_TYPE(); // !!! -> UNIT_TYPE() - case BOOLEAN(_): return definitions.boolean_TYPE(); - case BYTE(_) : return definitions.byte_TYPE(); - case SHORT(_) : return definitions.short_TYPE(); - case CHAR(_) : return definitions.char_TYPE(); - case INT(_) : return definitions.int_TYPE(); - case LONG(_) : return definitions.long_TYPE(); - case FLOAT(_) : return definitions.float_TYPE(); - case DOUBLE(_) : return definitions.double_TYPE(); - case SYMBOL_NAME(_): - case STRING(_) : return definitions.STRING_TYPE(); - case NULL : return definitions.ALLREF_TYPE(); - case ZERO : return definitions.ALL_TYPE(); - default : throw Debug.abort("unknown case", constant); - } - } - - //######################################################################## - // Public Methods - Typing type kinds - - /** Returns the type of the given type kind. */ - public Type type(ATypeKind kind) { - switch (kind) { - case UNIT: return definitions.void_TYPE(); // !!! -> UNIT_TYPE() - case BOOL: return definitions.boolean_TYPE(); - // !!! case U1 : return ?; - case U2 : return definitions.char_TYPE(); - // !!! case U4 : return ?; - // !!! case U8 : return ?; - case I1 : return definitions.byte_TYPE(); - case I2 : return definitions.short_TYPE(); - case I4 : return definitions.int_TYPE(); - case I8 : return definitions.long_TYPE(); - case R4 : return definitions.float_TYPE(); - case R8 : return definitions.double_TYPE(); - case REF : return definitions.ANYREF_TYPE(); - case STR : return definitions.STRING_TYPE(); - case NULL: return definitions.ALLREF_TYPE(); - case ZERO: return definitions.ALL_TYPE(); - default : throw Debug.abort("unknown case", kind); - } - } - - //######################################################################## - // Public Methods - Aliases for scala - - public Type[] computeType(ACode[] codes) { - return type(codes); - } - - public Type computeType(ACode code) { - return type(code); - } - - public Type computeType(ALocation location) { - return type(location); - } - - public Type computeType(AFunction function) { - return type(function); - } - - public Type computeType(APrimitive primitive) { - return type(primitive); - } - - public Type computeType(AConstant constant) { - return type(constant); - } - - public Type computeType(ATypeKind kind) { - return type(kind); - } - - //######################################################################## - // Private Methods - - /** Returns the application of given arguments to given type. */ - private Type apply(Type type, Type[] targs) { - switch (type) { - case PolyType(Symbol[] tparams, Type result): - return result.subst(tparams, targs); - default: - assert targs.length == 0: type + " -- " + Debug.show(targs); - return type; - } - } - - /** Returns the element type of the given array type. */ - public Type getArrayElementType(Type type) { // !!! public / private - switch (type) { - case TypeRef(_, Symbol symbol, Type[] args): - assert symbol == definitions.ARRAY_CLASS && args.length == 1: type; - return args[0]; - case UnboxedArrayType(Type element): - return element; - default: - throw Debug.abort("non-array type", type); - } - } - - /** Returns a method type with given argument and result types. */ - private Type getMethodType(Type targ1, Type result) { - return getMethodType(new Type[]{targ1}, result); - } - - /** Returns a method type with given argument and result types. */ - private Type getMethodType(Type targ1, Type targ2, Type result) { - return getMethodType(new Type[]{targ1, targ2}, result); - } - - /** Returns a method type with given argument and result types. */ - private Type getMethodType(Type[] targs, Type result) { - Symbol[] tparams = new Symbol[targs.length]; - for (int i = 0; i < tparams.length; i++) { - Name name = Name.fromString("v" + i); - tparams[i] = Symbol.NONE.newTerm( // !!! should be newVParam - Position.NOPOS, Modifiers.PARAM, name); - tparams[i].setType(targs[i]); - } - return Type.MethodType(tparams, result); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATypeKind.java b/sources/scalac/atree/ATypeKind.java deleted file mode 100644 index 1be2eb540d..0000000000 --- a/sources/scalac/atree/ATypeKind.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a type kind. */ -public class ATypeKind { - - //######################################################################## - // Public Cases - - /** The unit value */ - public case UNIT; - - /** A boolean value */ - public case BOOL; - - /** A 1-byte unsigned integer */ - public case U1; - - /** A 2-byte unsigned integer */ - public case U2; - - /** A 4-byte unsigned integer */ - public case U4; - - /** An 8-byte unsigned integer */ - public case U8; - - /** A 1-byte signed integer */ - public case I1; - - /** A 2-byte signed integer */ - public case I2; - - /** A 4-byte signed integer */ - public case I4; - - /** An 8-byte signed integer */ - public case I8; - - /** A 4-byte floating point number */ - public case R4; - - /** An 8-byte floating point number */ - public case R8; - - /** An object reference */ - public case REF; - - /** A string reference */ - public case STR; - - /** The null reference */ - public case NULL; - - /** The zero value */ - public case ZERO; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this type kind. */ - public String toString() { - switch (this) { - case UNIT: return "UNIT"; - case BOOL: return "BOOL"; - case U1 : return "U1"; - case U2 : return "U2"; - case U4 : return "U4"; - case U8 : return "U8"; - case I1 : return "I1"; - case I2 : return "I2"; - case I4 : return "I4"; - case I8 : return "I8"; - case R4 : return "R4"; - case R8 : return "R8"; - case REF : return "REF"; - case STR : return "STR"; - case NULL: return "NULL"; - case ZERO: return "ZERO"; - default : throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/backend/Primitive.java b/sources/scalac/backend/Primitive.java deleted file mode 100644 index 2c55a68dc8..0000000000 --- a/sources/scalac/backend/Primitive.java +++ /dev/null @@ -1,205 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// Old$Id$ -// $Id$ - -package scalac.backend; - -import scalac.util.Debug; - -/** - * Primitive functions. - * - * @author Michel Schinz, Philippe Altherr - * @version 1.0 - */ - -public class Primitive { - - // Non-primitive operations - public case NOT_A_PRIMITIVE; // not a primitive - - // Arithmetic unary operations - public case POS; // +x - public case NEG; // -x - public case NOT; // ~x - - // Arithmetic binary operations - public case ADD; // x + y - public case SUB; // x - y - public case MUL; // x * y - public case DIV; // x / y - public case MOD; // x % y - - // Bitwise operations - public case OR; // x | y - public case XOR; // x ^ y - public case AND; // x & y - - // Shift operations - public case LSL; // x << y - public case LSR; // x >>> y - public case ASR; // x >> y - - // Comparison operations - public case ID; // x eq y - public case NI; // x ne y - public case EQ; // x == y - public case NE; // x != y - public case LT; // x < y - public case LE; // x <= y - public case GE; // x > y - public case GT; // x >= y - - // Boolean unary operations - public case ZNOT; // !x - - // Boolean binary operations - public case ZOR; // x || y - public case ZAND; // x && y - - // Array operations - public case LENGTH; // x.length - public case APPLY; // x(y) - public case UPDATE; // x(y) = z - - // Any operations - public case IS; // x.is[y] - public case AS; // x.as[y] - public case EQUALS; // x.equals(y) - public case HASHCODE; // x.hashcode() - public case TOSTRING; // x.toString() - - // AnyRef operations - public case SYNCHRONIZED; // x.synchronized(y) - - // String operations - public case CONCAT; // String.valueOf(x)+String.valueOf(y) - - // Throwable operations - public case THROW; // throw x - - // Value types conversions - public case COERCE; // x.coerce() - - // RunTime operations - public case BOX; // RunTime.box_<X>(x) - public case UNBOX; // RunTime.unbox_<X>(x) - public case NEW_ZARRAY; // RunTime.zarray(x) - public case NEW_BARRAY; // RunTime.barray(x) - public case NEW_SARRAY; // RunTime.sarray(x) - public case NEW_CARRAY; // RunTime.carray(x) - public case NEW_IARRAY; // RunTime.iarray(x) - public case NEW_LARRAY; // RunTime.larray(x) - public case NEW_FARRAY; // RunTime.farray(x) - public case NEW_DARRAY; // RunTime.darray(x) - public case NEW_OARRAY; // RunTime.oarray(x) - public case ZARRAY_LENGTH; // RunTime.zarray_length(x) - public case BARRAY_LENGTH; // RunTime.barray_length(x) - public case SARRAY_LENGTH; // RunTime.sarray_length(x) - public case CARRAY_LENGTH; // RunTime.carray_length(x) - public case IARRAY_LENGTH; // RunTime.iarray_length(x) - public case LARRAY_LENGTH; // RunTime.larray_length(x) - public case FARRAY_LENGTH; // RunTime.farray_length(x) - public case DARRAY_LENGTH; // RunTime.darray_length(x) - public case OARRAY_LENGTH; // RunTime.oarray_length(x) - public case ZARRAY_GET; // RunTime.zarray_get(x,y) - public case BARRAY_GET; // RunTime.barray_get(x,y) - public case SARRAY_GET; // RunTime.sarray_get(x,y) - public case CARRAY_GET; // RunTime.carray_get(x,y) - public case IARRAY_GET; // RunTime.iarray_get(x,y) - public case LARRAY_GET; // RunTime.larray_get(x,y) - public case FARRAY_GET; // RunTime.farray_get(x,y) - public case DARRAY_GET; // RunTime.darray_get(x,y) - public case OARRAY_GET; // RunTime.oarray_get(x,y) - public case ZARRAY_SET; // RunTime.zarray(x,y,z) - public case BARRAY_SET; // RunTime.barray(x,y,z) - public case SARRAY_SET; // RunTime.sarray(x,y,z) - public case CARRAY_SET; // RunTime.carray(x,y,z) - public case IARRAY_SET; // RunTime.iarray(x,y,z) - public case LARRAY_SET; // RunTime.larray(x,y,z) - public case FARRAY_SET; // RunTime.farray(x,y,z) - public case DARRAY_SET; // RunTime.darray(x,y,z) - public case OARRAY_SET; // RunTime.oarray(x,y,z) - - public case B2B; // RunTime.b2b(x) - public case B2S; // RunTime.b2s(x) - public case B2C; // RunTime.b2c(x) - public case B2I; // RunTime.b2i(x) - public case B2L; // RunTime.b2l(x) - public case B2F; // RunTime.b2f(x) - public case B2D; // RunTime.b2d(x) - public case S2B; // RunTime.s2b(x) - public case S2S; // RunTime.s2s(x) - public case S2C; // RunTime.s2c(x) - public case S2I; // RunTime.s2i(x) - public case S2L; // RunTime.s2l(x) - public case S2F; // RunTime.s2f(x) - public case S2D; // RunTime.s2d(x) - public case C2B; // RunTime.c2b(x) - public case C2S; // RunTime.c2s(x) - public case C2C; // RunTime.c2c(x) - public case C2I; // RunTime.c2i(x) - public case C2L; // RunTime.c2l(x) - public case C2F; // RunTime.c2f(x) - public case C2D; // RunTime.c2d(x) - public case I2B; // RunTime.i2b(x) - public case I2S; // RunTime.i2s(x) - public case I2C; // RunTime.i2c(x) - public case I2I; // RunTime.i2i(x) - public case I2L; // RunTime.i2l(x) - public case I2F; // RunTime.i2f(x) - public case I2D; // RunTime.i2d(x) - public case L2B; // RunTime.l2b(x) - public case L2S; // RunTime.l2s(x) - public case L2C; // RunTime.l2c(x) - public case L2I; // RunTime.l2i(x) - public case L2L; // RunTime.l2l(x) - public case L2F; // RunTime.l2f(x) - public case L2D; // RunTime.l2d(x) - public case F2B; // RunTime.f2b(x) - public case F2S; // RunTime.f2s(x) - public case F2C; // RunTime.f2c(x) - public case F2I; // RunTime.f2i(x) - public case F2L; // RunTime.f2l(x) - public case F2F; // RunTime.f2f(x) - public case F2D; // RunTime.f2d(x) - public case D2B; // RunTime.d2b(x) - public case D2S; // RunTime.d2s(x) - public case D2C; // RunTime.d2c(x) - public case D2I; // RunTime.d2i(x) - public case D2L; // RunTime.d2l(x) - public case D2F; // RunTime.d2f(x) - public case D2D; // RunTime.d2d(x) - - /** Return negated version of comparison primitive. */ - public Primitive negate() { - switch (this) { - case LT: return Primitive.GE; - case LE: return Primitive.GT; - case EQ: return Primitive.NE; - case NE: return Primitive.EQ; - case GE: return Primitive.LT; - case GT: return Primitive.LE; - default: throw Debug.abort("unknown primitive", this); - } - } - - /** Return primitive with arguments swapped (e.g. <= is turned - ** into =>). */ - public Primitive swap() { - switch (this) { - case LT: return Primitive.GT; - case LE: return Primitive.GE; - case EQ: return Primitive.EQ; - case NE: return Primitive.NE; - case GE: return Primitive.LE; - case GT: return Primitive.LT; - default: throw Debug.abort("unknown primitive", this); - } - } -} diff --git a/sources/scalac/backend/Primitives.java b/sources/scalac/backend/Primitives.java deleted file mode 100644 index fb2b49a3b0..0000000000 --- a/sources/scalac/backend/Primitives.java +++ /dev/null @@ -1,1304 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Primitives.java,v 1.12 2002/11/19 12:01:11 paltherr Exp $ -// $Id$ - -package scalac.backend; - -import java.util.Map; -import java.util.HashMap; - -import scalac.Global; -import scalac.symtab.Definitions; -import scalac.symtab.TypeTags; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -/** - * Primitive functions. - * - * @author Michel Schinz, Philippe Altherr - * @version 1.0 - */ - -public class Primitives { - - //######################################################################## - // Primitives constants - - private static final Name RUNTIME_N = Name.fromString("RunTime"); - - private static final Name ZARRAY_N = Name.fromString("zarray"); - private static final Name BARRAY_N = Name.fromString("barray"); - private static final Name SARRAY_N = Name.fromString("sarray"); - private static final Name CARRAY_N = Name.fromString("carray"); - private static final Name IARRAY_N = Name.fromString("iarray"); - private static final Name LARRAY_N = Name.fromString("larray"); - private static final Name FARRAY_N = Name.fromString("farray"); - private static final Name DARRAY_N = Name.fromString("darray"); - private static final Name OARRAY_N = Name.fromString("oarray"); - - private static final Name ZARRAY_LENGTH_N=Name.fromString("zarray_length"); - private static final Name BARRAY_LENGTH_N=Name.fromString("barray_length"); - private static final Name SARRAY_LENGTH_N=Name.fromString("sarray_length"); - private static final Name CARRAY_LENGTH_N=Name.fromString("carray_length"); - private static final Name IARRAY_LENGTH_N=Name.fromString("iarray_length"); - private static final Name LARRAY_LENGTH_N=Name.fromString("larray_length"); - private static final Name FARRAY_LENGTH_N=Name.fromString("farray_length"); - private static final Name DARRAY_LENGTH_N=Name.fromString("darray_length"); - private static final Name OARRAY_LENGTH_N=Name.fromString("oarray_length"); - - private static final Name ZARRAY_GET_N = Name.fromString("zarray_get"); - private static final Name BARRAY_GET_N = Name.fromString("barray_get"); - private static final Name SARRAY_GET_N = Name.fromString("sarray_get"); - private static final Name CARRAY_GET_N = Name.fromString("carray_get"); - private static final Name IARRAY_GET_N = Name.fromString("iarray_get"); - private static final Name LARRAY_GET_N = Name.fromString("larray_get"); - private static final Name FARRAY_GET_N = Name.fromString("farray_get"); - private static final Name DARRAY_GET_N = Name.fromString("darray_get"); - private static final Name OARRAY_GET_N = Name.fromString("oarray_get"); - - private static final Name ZARRAY_SET_N = Name.fromString("zarray_set"); - private static final Name BARRAY_SET_N = Name.fromString("barray_set"); - private static final Name SARRAY_SET_N = Name.fromString("sarray_set"); - private static final Name CARRAY_SET_N = Name.fromString("carray_set"); - private static final Name IARRAY_SET_N = Name.fromString("iarray_set"); - private static final Name LARRAY_SET_N = Name.fromString("larray_set"); - private static final Name FARRAY_SET_N = Name.fromString("farray_set"); - private static final Name DARRAY_SET_N = Name.fromString("darray_set"); - private static final Name OARRAY_SET_N = Name.fromString("oarray_set"); - - private static final Name BOX_UVALUE_N = Name.fromString("box_uvalue"); - private static final Name BOX_ZVALUE_N = Name.fromString("box_zvalue"); - private static final Name BOX_BVALUE_N = Name.fromString("box_bvalue"); - private static final Name BOX_SVALUE_N = Name.fromString("box_svalue"); - private static final Name BOX_CVALUE_N = Name.fromString("box_cvalue"); - private static final Name BOX_IVALUE_N = Name.fromString("box_ivalue"); - private static final Name BOX_LVALUE_N = Name.fromString("box_lvalue"); - private static final Name BOX_FVALUE_N = Name.fromString("box_fvalue"); - private static final Name BOX_DVALUE_N = Name.fromString("box_dvalue"); - - private static final Name BOX_ZARRAY_N = Name.fromString("box_zarray"); - private static final Name BOX_BARRAY_N = Name.fromString("box_barray"); - private static final Name BOX_SARRAY_N = Name.fromString("box_sarray"); - private static final Name BOX_CARRAY_N = Name.fromString("box_carray"); - private static final Name BOX_IARRAY_N = Name.fromString("box_iarray"); - private static final Name BOX_LARRAY_N = Name.fromString("box_larray"); - private static final Name BOX_FARRAY_N = Name.fromString("box_farray"); - private static final Name BOX_DARRAY_N = Name.fromString("box_darray"); - private static final Name BOX_OARRAY_N = Name.fromString("box_oarray"); - private static final Name BOX__ARRAY_N = Name.fromString("box__array"); - - private static final Name UNBOX_UVALUE_N = Name.fromString("unbox_uvalue"); - private static final Name UNBOX_ZVALUE_N = Name.fromString("unbox_zvalue"); - private static final Name UNBOX_BVALUE_N = Name.fromString("unbox_bvalue"); - private static final Name UNBOX_SVALUE_N = Name.fromString("unbox_svalue"); - private static final Name UNBOX_CVALUE_N = Name.fromString("unbox_cvalue"); - private static final Name UNBOX_IVALUE_N = Name.fromString("unbox_ivalue"); - private static final Name UNBOX_LVALUE_N = Name.fromString("unbox_lvalue"); - private static final Name UNBOX_FVALUE_N = Name.fromString("unbox_fvalue"); - private static final Name UNBOX_DVALUE_N = Name.fromString("unbox_dvalue"); - - private static final Name UNBOX_ZARRAY_N = Name.fromString("unbox_zarray"); - private static final Name UNBOX_BARRAY_N = Name.fromString("unbox_barray"); - private static final Name UNBOX_SARRAY_N = Name.fromString("unbox_sarray"); - private static final Name UNBOX_CARRAY_N = Name.fromString("unbox_carray"); - private static final Name UNBOX_IARRAY_N = Name.fromString("unbox_iarray"); - private static final Name UNBOX_LARRAY_N = Name.fromString("unbox_larray"); - private static final Name UNBOX_FARRAY_N = Name.fromString("unbox_farray"); - private static final Name UNBOX_DARRAY_N = Name.fromString("unbox_darray"); - private static final Name UNBOX_OARRAY_N = Name.fromString("unbox_oarray"); - private static final Name UNBOX__ARRAY_N = Name.fromString("unbox__array"); - - private static final Name B2B_N = Name.fromString("b2b"); - private static final Name B2S_N = Name.fromString("b2s"); - private static final Name B2C_N = Name.fromString("b2c"); - private static final Name B2I_N = Name.fromString("b2i"); - private static final Name B2L_N = Name.fromString("b2l"); - private static final Name B2F_N = Name.fromString("b2f"); - private static final Name B2D_N = Name.fromString("b2d"); - private static final Name S2B_N = Name.fromString("s2b"); - private static final Name S2S_N = Name.fromString("s2s"); - private static final Name S2C_N = Name.fromString("s2c"); - private static final Name S2I_N = Name.fromString("s2i"); - private static final Name S2L_N = Name.fromString("s2l"); - private static final Name S2F_N = Name.fromString("s2f"); - private static final Name S2D_N = Name.fromString("s2d"); - private static final Name C2B_N = Name.fromString("c2b"); - private static final Name C2S_N = Name.fromString("c2s"); - private static final Name C2C_N = Name.fromString("c2c"); - private static final Name C2I_N = Name.fromString("c2i"); - private static final Name C2L_N = Name.fromString("c2l"); - private static final Name C2F_N = Name.fromString("c2f"); - private static final Name C2D_N = Name.fromString("c2d"); - private static final Name I2B_N = Name.fromString("i2b"); - private static final Name I2S_N = Name.fromString("i2s"); - private static final Name I2C_N = Name.fromString("i2c"); - private static final Name I2I_N = Name.fromString("i2i"); - private static final Name I2L_N = Name.fromString("i2l"); - private static final Name I2F_N = Name.fromString("i2f"); - private static final Name I2D_N = Name.fromString("i2d"); - private static final Name L2B_N = Name.fromString("l2b"); - private static final Name L2S_N = Name.fromString("l2s"); - private static final Name L2C_N = Name.fromString("l2c"); - private static final Name L2I_N = Name.fromString("l2i"); - private static final Name L2L_N = Name.fromString("l2l"); - private static final Name L2F_N = Name.fromString("l2f"); - private static final Name L2D_N = Name.fromString("l2d"); - private static final Name F2B_N = Name.fromString("f2b"); - private static final Name F2S_N = Name.fromString("f2s"); - private static final Name F2C_N = Name.fromString("f2c"); - private static final Name F2I_N = Name.fromString("f2i"); - private static final Name F2L_N = Name.fromString("f2l"); - private static final Name F2F_N = Name.fromString("f2f"); - private static final Name F2D_N = Name.fromString("f2d"); - private static final Name D2B_N = Name.fromString("d2b"); - private static final Name D2S_N = Name.fromString("d2s"); - private static final Name D2C_N = Name.fromString("d2c"); - private static final Name D2I_N = Name.fromString("d2i"); - private static final Name D2L_N = Name.fromString("d2l"); - private static final Name D2F_N = Name.fromString("d2f"); - private static final Name D2D_N = Name.fromString("d2d"); - - //######################################################################## - // Primitives state - - private final Global global; - private final Definitions definitions; - private final Map/*<Symbol,Primitive>*/ primitives; - private final SymbolNameWriter jreNameWriter; - private final SymbolNameWriter clrNameWriter; - - public final Symbol RUNTIME; - - public final Symbol NEW_ZARRAY; - public final Symbol NEW_BARRAY; - public final Symbol NEW_SARRAY; - public final Symbol NEW_CARRAY; - public final Symbol NEW_IARRAY; - public final Symbol NEW_LARRAY; - public final Symbol NEW_FARRAY; - public final Symbol NEW_DARRAY; - public final Symbol NEW_OARRAY; - - public final Symbol ZARRAY_LENGTH; - public final Symbol BARRAY_LENGTH; - public final Symbol SARRAY_LENGTH; - public final Symbol CARRAY_LENGTH; - public final Symbol IARRAY_LENGTH; - public final Symbol LARRAY_LENGTH; - public final Symbol FARRAY_LENGTH; - public final Symbol DARRAY_LENGTH; - public final Symbol OARRAY_LENGTH; - - public final Symbol ZARRAY_GET; - public final Symbol BARRAY_GET; - public final Symbol SARRAY_GET; - public final Symbol CARRAY_GET; - public final Symbol IARRAY_GET; - public final Symbol LARRAY_GET; - public final Symbol FARRAY_GET; - public final Symbol DARRAY_GET; - public final Symbol OARRAY_GET; - - public final Symbol ZARRAY_SET; - public final Symbol BARRAY_SET; - public final Symbol SARRAY_SET; - public final Symbol CARRAY_SET; - public final Symbol IARRAY_SET; - public final Symbol LARRAY_SET; - public final Symbol FARRAY_SET; - public final Symbol DARRAY_SET; - public final Symbol OARRAY_SET; - - public final Symbol BOX_UVALUE; - public final Symbol BOX_ZVALUE; - public final Symbol BOX_BVALUE; - public final Symbol BOX_SVALUE; - public final Symbol BOX_CVALUE; - public final Symbol BOX_IVALUE; - public final Symbol BOX_LVALUE; - public final Symbol BOX_FVALUE; - public final Symbol BOX_DVALUE; - - public final Symbol BOX_ZARRAY; - public final Symbol BOX_BARRAY; - public final Symbol BOX_SARRAY; - public final Symbol BOX_CARRAY; - public final Symbol BOX_IARRAY; - public final Symbol BOX_LARRAY; - public final Symbol BOX_FARRAY; - public final Symbol BOX_DARRAY; - public final Symbol BOX_OARRAY; - public final Symbol BOX__ARRAY; - - public final Symbol UNBOX_UVALUE; - public final Symbol UNBOX_ZVALUE; - public final Symbol UNBOX_BVALUE; - public final Symbol UNBOX_SVALUE; - public final Symbol UNBOX_CVALUE; - public final Symbol UNBOX_IVALUE; - public final Symbol UNBOX_LVALUE; - public final Symbol UNBOX_FVALUE; - public final Symbol UNBOX_DVALUE; - - public final Symbol UNBOX_ZARRAY; - public final Symbol UNBOX_BARRAY; - public final Symbol UNBOX_SARRAY; - public final Symbol UNBOX_CARRAY; - public final Symbol UNBOX_IARRAY; - public final Symbol UNBOX_LARRAY; - public final Symbol UNBOX_FARRAY; - public final Symbol UNBOX_DARRAY; - public final Symbol UNBOX_OARRAY; - public final Symbol UNBOX__ARRAY; - - public final Symbol B2B; - public final Symbol B2S; - public final Symbol B2C; - public final Symbol B2I; - public final Symbol B2L; - public final Symbol B2F; - public final Symbol B2D; - public final Symbol S2B; - public final Symbol S2S; - public final Symbol S2C; - public final Symbol S2I; - public final Symbol S2L; - public final Symbol S2F; - public final Symbol S2D; - public final Symbol C2B; - public final Symbol C2S; - public final Symbol C2C; - public final Symbol C2I; - public final Symbol C2L; - public final Symbol C2F; - public final Symbol C2D; - public final Symbol I2B; - public final Symbol I2S; - public final Symbol I2C; - public final Symbol I2I; - public final Symbol I2L; - public final Symbol I2F; - public final Symbol I2D; - public final Symbol L2B; - public final Symbol L2S; - public final Symbol L2C; - public final Symbol L2I; - public final Symbol L2L; - public final Symbol L2F; - public final Symbol L2D; - public final Symbol F2B; - public final Symbol F2S; - public final Symbol F2C; - public final Symbol F2I; - public final Symbol F2L; - public final Symbol F2F; - public final Symbol F2D; - public final Symbol D2B; - public final Symbol D2S; - public final Symbol D2C; - public final Symbol D2I; - public final Symbol D2L; - public final Symbol D2F; - public final Symbol D2D; - - //######################################################################## - // Primitives constructor - - public Primitives(Global global) { - this.global = global; - this.definitions = global.definitions; - this.primitives = new HashMap(); - this.jreNameWriter = new SymbolNameWriter().setClassSeparator('$'); - this.clrNameWriter = new SymbolNameWriter(); - this.RUNTIME = definitions.getModule("scala.runtime.RunTime"); - this.NEW_ZARRAY = getUniqueTerm(RUNTIME, ZARRAY_N); - this.NEW_BARRAY = getUniqueTerm(RUNTIME, BARRAY_N); - this.NEW_SARRAY = getUniqueTerm(RUNTIME, SARRAY_N); - this.NEW_CARRAY = getUniqueTerm(RUNTIME, CARRAY_N); - this.NEW_IARRAY = getUniqueTerm(RUNTIME, IARRAY_N); - this.NEW_LARRAY = getUniqueTerm(RUNTIME, LARRAY_N); - this.NEW_FARRAY = getUniqueTerm(RUNTIME, FARRAY_N); - this.NEW_DARRAY = getUniqueTerm(RUNTIME, DARRAY_N); - this.NEW_OARRAY = getUniqueTerm(RUNTIME, OARRAY_N); - this.ZARRAY_LENGTH = getUniqueTerm(RUNTIME, ZARRAY_LENGTH_N); - this.BARRAY_LENGTH = getUniqueTerm(RUNTIME, BARRAY_LENGTH_N); - this.SARRAY_LENGTH = getUniqueTerm(RUNTIME, SARRAY_LENGTH_N); - this.CARRAY_LENGTH = getUniqueTerm(RUNTIME, CARRAY_LENGTH_N); - this.IARRAY_LENGTH = getUniqueTerm(RUNTIME, IARRAY_LENGTH_N); - this.LARRAY_LENGTH = getUniqueTerm(RUNTIME, LARRAY_LENGTH_N); - this.FARRAY_LENGTH = getUniqueTerm(RUNTIME, FARRAY_LENGTH_N); - this.DARRAY_LENGTH = getUniqueTerm(RUNTIME, DARRAY_LENGTH_N); - this.OARRAY_LENGTH = getUniqueTerm(RUNTIME, OARRAY_LENGTH_N); - this.ZARRAY_GET = getUniqueTerm(RUNTIME, ZARRAY_GET_N); - this.BARRAY_GET = getUniqueTerm(RUNTIME, BARRAY_GET_N); - this.SARRAY_GET = getUniqueTerm(RUNTIME, SARRAY_GET_N); - this.CARRAY_GET = getUniqueTerm(RUNTIME, CARRAY_GET_N); - this.IARRAY_GET = getUniqueTerm(RUNTIME, IARRAY_GET_N); - this.LARRAY_GET = getUniqueTerm(RUNTIME, LARRAY_GET_N); - this.FARRAY_GET = getUniqueTerm(RUNTIME, FARRAY_GET_N); - this.DARRAY_GET = getUniqueTerm(RUNTIME, DARRAY_GET_N); - this.OARRAY_GET = getUniqueTerm(RUNTIME, OARRAY_GET_N); - this.ZARRAY_SET = getUniqueTerm(RUNTIME, ZARRAY_SET_N); - this.BARRAY_SET = getUniqueTerm(RUNTIME, BARRAY_SET_N); - this.SARRAY_SET = getUniqueTerm(RUNTIME, SARRAY_SET_N); - this.CARRAY_SET = getUniqueTerm(RUNTIME, CARRAY_SET_N); - this.IARRAY_SET = getUniqueTerm(RUNTIME, IARRAY_SET_N); - this.LARRAY_SET = getUniqueTerm(RUNTIME, LARRAY_SET_N); - this.FARRAY_SET = getUniqueTerm(RUNTIME, FARRAY_SET_N); - this.DARRAY_SET = getUniqueTerm(RUNTIME, DARRAY_SET_N); - this.OARRAY_SET = getUniqueTerm(RUNTIME, OARRAY_SET_N); - this.BOX_UVALUE = getUniqueTerm(RUNTIME, BOX_UVALUE_N); - this.BOX_ZVALUE = getUniqueTerm(RUNTIME, BOX_ZVALUE_N); - this.BOX_BVALUE = getUniqueTerm(RUNTIME, BOX_BVALUE_N); - this.BOX_SVALUE = getUniqueTerm(RUNTIME, BOX_SVALUE_N); - this.BOX_CVALUE = getUniqueTerm(RUNTIME, BOX_CVALUE_N); - this.BOX_IVALUE = getUniqueTerm(RUNTIME, BOX_IVALUE_N); - this.BOX_LVALUE = getUniqueTerm(RUNTIME, BOX_LVALUE_N); - this.BOX_FVALUE = getUniqueTerm(RUNTIME, BOX_FVALUE_N); - this.BOX_DVALUE = getUniqueTerm(RUNTIME, BOX_DVALUE_N); - this.BOX_ZARRAY = getUniqueTerm(RUNTIME, BOX_ZARRAY_N); - this.BOX_BARRAY = getUniqueTerm(RUNTIME, BOX_BARRAY_N); - this.BOX_SARRAY = getUniqueTerm(RUNTIME, BOX_SARRAY_N); - this.BOX_CARRAY = getUniqueTerm(RUNTIME, BOX_CARRAY_N); - this.BOX_IARRAY = getUniqueTerm(RUNTIME, BOX_IARRAY_N); - this.BOX_LARRAY = getUniqueTerm(RUNTIME, BOX_LARRAY_N); - this.BOX_FARRAY = getUniqueTerm(RUNTIME, BOX_FARRAY_N); - this.BOX_DARRAY = getUniqueTerm(RUNTIME, BOX_DARRAY_N); - this.BOX_OARRAY = getUniqueTerm(RUNTIME, BOX_OARRAY_N); - this.BOX__ARRAY = getUniqueTerm(RUNTIME, BOX__ARRAY_N); - this.UNBOX_UVALUE = getUniqueTerm(RUNTIME, UNBOX_UVALUE_N); - this.UNBOX_ZVALUE = getUniqueTerm(RUNTIME, UNBOX_ZVALUE_N); - this.UNBOX_BVALUE = getUniqueTerm(RUNTIME, UNBOX_BVALUE_N); - this.UNBOX_SVALUE = getUniqueTerm(RUNTIME, UNBOX_SVALUE_N); - this.UNBOX_CVALUE = getUniqueTerm(RUNTIME, UNBOX_CVALUE_N); - this.UNBOX_IVALUE = getUniqueTerm(RUNTIME, UNBOX_IVALUE_N); - this.UNBOX_LVALUE = getUniqueTerm(RUNTIME, UNBOX_LVALUE_N); - this.UNBOX_FVALUE = getUniqueTerm(RUNTIME, UNBOX_FVALUE_N); - this.UNBOX_DVALUE = getUniqueTerm(RUNTIME, UNBOX_DVALUE_N); - this.UNBOX_ZARRAY = getUniqueTerm(RUNTIME, UNBOX_ZARRAY_N); - this.UNBOX_BARRAY = getUniqueTerm(RUNTIME, UNBOX_BARRAY_N); - this.UNBOX_SARRAY = getUniqueTerm(RUNTIME, UNBOX_SARRAY_N); - this.UNBOX_CARRAY = getUniqueTerm(RUNTIME, UNBOX_CARRAY_N); - this.UNBOX_IARRAY = getUniqueTerm(RUNTIME, UNBOX_IARRAY_N); - this.UNBOX_LARRAY = getUniqueTerm(RUNTIME, UNBOX_LARRAY_N); - this.UNBOX_FARRAY = getUniqueTerm(RUNTIME, UNBOX_FARRAY_N); - this.UNBOX_DARRAY = getUniqueTerm(RUNTIME, UNBOX_DARRAY_N); - this.UNBOX_OARRAY = getUniqueTerm(RUNTIME, UNBOX_OARRAY_N); - this.UNBOX__ARRAY = getUniqueTerm(RUNTIME, UNBOX__ARRAY_N); - this.B2B = getUniqueTerm(RUNTIME, B2B_N); - this.B2S = getUniqueTerm(RUNTIME, B2S_N); - this.B2C = getUniqueTerm(RUNTIME, B2C_N); - this.B2I = getUniqueTerm(RUNTIME, B2I_N); - this.B2L = getUniqueTerm(RUNTIME, B2L_N); - this.B2F = getUniqueTerm(RUNTIME, B2F_N); - this.B2D = getUniqueTerm(RUNTIME, B2D_N); - this.S2B = getUniqueTerm(RUNTIME, S2B_N); - this.S2S = getUniqueTerm(RUNTIME, S2S_N); - this.S2C = getUniqueTerm(RUNTIME, S2C_N); - this.S2I = getUniqueTerm(RUNTIME, S2I_N); - this.S2L = getUniqueTerm(RUNTIME, S2L_N); - this.S2F = getUniqueTerm(RUNTIME, S2F_N); - this.S2D = getUniqueTerm(RUNTIME, S2D_N); - this.C2B = getUniqueTerm(RUNTIME, C2B_N); - this.C2S = getUniqueTerm(RUNTIME, C2S_N); - this.C2C = getUniqueTerm(RUNTIME, C2C_N); - this.C2I = getUniqueTerm(RUNTIME, C2I_N); - this.C2L = getUniqueTerm(RUNTIME, C2L_N); - this.C2F = getUniqueTerm(RUNTIME, C2F_N); - this.C2D = getUniqueTerm(RUNTIME, C2D_N); - this.I2B = getUniqueTerm(RUNTIME, I2B_N); - this.I2S = getUniqueTerm(RUNTIME, I2S_N); - this.I2C = getUniqueTerm(RUNTIME, I2C_N); - this.I2I = getUniqueTerm(RUNTIME, I2I_N); - this.I2L = getUniqueTerm(RUNTIME, I2L_N); - this.I2F = getUniqueTerm(RUNTIME, I2F_N); - this.I2D = getUniqueTerm(RUNTIME, I2D_N); - this.L2B = getUniqueTerm(RUNTIME, L2B_N); - this.L2S = getUniqueTerm(RUNTIME, L2S_N); - this.L2C = getUniqueTerm(RUNTIME, L2C_N); - this.L2I = getUniqueTerm(RUNTIME, L2I_N); - this.L2L = getUniqueTerm(RUNTIME, L2L_N); - this.L2F = getUniqueTerm(RUNTIME, L2F_N); - this.L2D = getUniqueTerm(RUNTIME, L2D_N); - this.F2B = getUniqueTerm(RUNTIME, F2B_N); - this.F2S = getUniqueTerm(RUNTIME, F2S_N); - this.F2C = getUniqueTerm(RUNTIME, F2C_N); - this.F2I = getUniqueTerm(RUNTIME, F2I_N); - this.F2L = getUniqueTerm(RUNTIME, F2L_N); - this.F2F = getUniqueTerm(RUNTIME, F2F_N); - this.F2D = getUniqueTerm(RUNTIME, F2D_N); - this.D2B = getUniqueTerm(RUNTIME, D2B_N); - this.D2S = getUniqueTerm(RUNTIME, D2S_N); - this.D2C = getUniqueTerm(RUNTIME, D2C_N); - this.D2I = getUniqueTerm(RUNTIME, D2I_N); - this.D2L = getUniqueTerm(RUNTIME, D2L_N); - this.D2F = getUniqueTerm(RUNTIME, D2F_N); - this.D2D = getUniqueTerm(RUNTIME, D2D_N); - initPrimitives(); - } - - //######################################################################## - // Private interface - - private Symbol getUniqueTerm(Symbol owner, Name name) { - Symbol symbol = getTerm(owner, name); - assert !symbol.isOverloaded() : - Debug.show(owner) + "." + name + " -> " + Debug.show(symbol); - return symbol; - } - - private Symbol getTerm(Symbol owner, Name name) { - Symbol symbol = owner.lookup(name); - assert symbol != Symbol.NONE : Debug.show(owner) + "." + name; - return symbol; - } - - private void initPrimitives() { - Definitions defs = definitions; - - // scala.Any - addPrimitive(defs.ANY_IS_ERASED, Primitive.IS); - addPrimitive(defs.ANY_AS_ERASED, Primitive.AS); - addPrimitive(defs.ANY_EQEQ, Primitive.EQ); - addPrimitive(defs.ANY_BANGEQ, Primitive.NE); - // !!! addPrimitive(defs.ANY_EQUALS, Primitive.EQUALS); - addPrimitive(defs.ANY_HASHCODE, Primitive.HASHCODE); - addPrimitive(defs.ANY_TOSTRING, Primitive.TOSTRING); - - // scala.Unit - addAll(defs.UNIT_CLASS, Names.EQ, Primitive.EQ, 1); - addAll(defs.UNIT_CLASS, Names.NE, Primitive.NE, 1); - addAll(defs.UNIT_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.UNIT_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.UNIT_CLASS, Names.toString, Primitive.TOSTRING, 1); - // !!! addAll(defs.UNIT_CLASS, Names.ADD, Primitive.CONCAT, 1); - - // scala.Boolean - //addAll(defs.BOOLEAN_CLASS, Names.EQ, Primitive.EQ, 2); - addAllPrimitive(defs.BOOLEAN_CLASS, Names.EQ, Primitive.EQ, 1); - //addAll(defs.BOOLEAN_CLASS, Names.NE, Primitive.NE, 2); - addAllPrimitive(defs.BOOLEAN_CLASS, Names.NE, Primitive.NE, 1); - addAll(defs.BOOLEAN_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.BOOLEAN_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.BOOLEAN_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.BOOLEAN_CLASS, Names.ZNOT, Primitive.ZNOT, 1); - addAll(defs.BOOLEAN_CLASS, Names.OR, Primitive.OR, 1); - addAll(defs.BOOLEAN_CLASS, Names.XOR, Primitive.XOR, 1); - addAll(defs.BOOLEAN_CLASS, Names.AND, Primitive.AND, 1); - addAll(defs.BOOLEAN_CLASS, Names.ZOR, Primitive.ZOR, 1); - addAll(defs.BOOLEAN_CLASS, Names.ZAND, Primitive.ZAND, 1); - // !!! addAll(defs.BOOLEAN_CLASS, Names.ADD, Primitive.CONCAT, 1); - - // scala.Byte - addAll(defs.BYTE_CLASS, Names.coerce, Primitive.COERCE, 5); - //addAll(defs.BYTE_CLASS, Names.EQ, Primitive.EQ, 5); - addAllPrimitive(defs.BYTE_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.BYTE_CLASS, Names.NE, Primitive.NE, 5); - addAllPrimitive(defs.BYTE_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.BYTE_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.BYTE_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.BYTE_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.BYTE_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.BYTE_CLASS, 7); - addSub(defs.BYTE_CLASS, 7); - addAll(defs.BYTE_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.BYTE_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.BYTE_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.BYTE_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.BYTE_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.BYTE_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.BYTE_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.BYTE_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.BYTE_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.BYTE_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.BYTE_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.BYTE_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.BYTE_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Short - addAll(defs.SHORT_CLASS, Names.coerce, Primitive.COERCE, 4); - //addAll(defs.SHORT_CLASS, Names.EQ, Primitive.EQ, 5); - addAllPrimitive(defs.SHORT_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.SHORT_CLASS, Names.NE, Primitive.NE, 5); - addAllPrimitive(defs.SHORT_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.SHORT_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.SHORT_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.SHORT_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.SHORT_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.SHORT_CLASS, 7); - addSub(defs.SHORT_CLASS, 7); - addAll(defs.SHORT_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.SHORT_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.SHORT_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.SHORT_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.SHORT_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.SHORT_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.SHORT_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.SHORT_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.SHORT_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.SHORT_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.SHORT_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.SHORT_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.SHORT_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Char - addAll(defs.CHAR_CLASS, Names.coerce, Primitive.COERCE, 4); - //addAll(defs.CHAR_CLASS, Names.EQ, Primitive.EQ, 5); - addAllPrimitive(defs.CHAR_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.CHAR_CLASS, Names.NE, Primitive.NE, 5); - addAllPrimitive(defs.CHAR_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.CHAR_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.CHAR_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.CHAR_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.CHAR_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.CHAR_CLASS, 7); - addSub(defs.CHAR_CLASS, 7); - addAll(defs.CHAR_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.CHAR_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.CHAR_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.CHAR_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.CHAR_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.CHAR_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.CHAR_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.CHAR_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.CHAR_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.CHAR_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.CHAR_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.CHAR_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.CHAR_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Int - addAll(defs.INT_CLASS, Names.coerce, Primitive.COERCE, 3); - //addAll(defs.INT_CLASS, Names.EQ, Primitive.EQ, 5); - addAllPrimitive(defs.INT_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.INT_CLASS, Names.NE, Primitive.NE, 5); - addAllPrimitive(defs.INT_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.INT_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.INT_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.INT_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.INT_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.INT_CLASS, 7); - addSub(defs.INT_CLASS, 7); - addAll(defs.INT_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.INT_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.INT_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.INT_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.INT_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.INT_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.INT_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.INT_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.INT_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.INT_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.INT_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.INT_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.INT_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Long - addAll(defs.LONG_CLASS, Names.coerce, Primitive.COERCE, 2); - //addAll(defs.LONG_CLASS, Names.EQ, Primitive.EQ, 4); - addAllPrimitive(defs.LONG_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.LONG_CLASS, Names.NE, Primitive.NE, 4); - addAllPrimitive(defs.LONG_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.LONG_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.LONG_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.LONG_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.LONG_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.LONG_CLASS, 7); - addSub(defs.LONG_CLASS, 7); - addAll(defs.LONG_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.LONG_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.LONG_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.LONG_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.LONG_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.LONG_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.LONG_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.LONG_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.LONG_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.LONG_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.LONG_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.LONG_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.LONG_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Float - addAll(defs.FLOAT_CLASS, Names.coerce, Primitive.COERCE, 1); - //addAll(defs.FLOAT_CLASS, Names.EQ, Primitive.EQ, 3); - addAllPrimitive(defs.FLOAT_CLASS, Names.EQ, Primitive.EQ, 2); - //addAll(defs.FLOAT_CLASS, Names.NE, Primitive.NE, 3); - addAllPrimitive(defs.FLOAT_CLASS, Names.NE, Primitive.NE, 2); - //addAll(defs.FLOAT_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.FLOAT_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.FLOAT_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAdd(defs.FLOAT_CLASS, 2); - addSub(defs.FLOAT_CLASS, 2); - addAll(defs.FLOAT_CLASS, Names.MUL, Primitive.MUL, 2); - addAll(defs.FLOAT_CLASS, Names.DIV, Primitive.DIV, 2); - addAll(defs.FLOAT_CLASS, Names.MOD, Primitive.MOD, 2); - addAll(defs.FLOAT_CLASS, Names.LT, Primitive.LT, 2); - addAll(defs.FLOAT_CLASS, Names.LE, Primitive.LE, 2); - addAll(defs.FLOAT_CLASS, Names.GT, Primitive.GT, 2); - addAll(defs.FLOAT_CLASS, Names.GE, Primitive.GE, 2); - - // scala.Double - //addAll(defs.DOUBLE_CLASS, Names.EQ, Primitive.EQ, 2); - addAllPrimitive(defs.DOUBLE_CLASS, Names.EQ, Primitive.EQ, 1); - //addAll(defs.DOUBLE_CLASS, Names.NE, Primitive.NE, 2); - addAllPrimitive(defs.DOUBLE_CLASS, Names.NE, Primitive.NE, 1); - //addAll(defs.DOUBLE_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.DOUBLE_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.DOUBLE_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAdd(defs.DOUBLE_CLASS, 1); - addSub(defs.DOUBLE_CLASS, 1); - addAll(defs.DOUBLE_CLASS, Names.MUL, Primitive.MUL, 1); - addAll(defs.DOUBLE_CLASS, Names.DIV, Primitive.DIV, 1); - addAll(defs.DOUBLE_CLASS, Names.MOD, Primitive.MOD, 1); - addAll(defs.DOUBLE_CLASS, Names.LT, Primitive.LT, 1); - addAll(defs.DOUBLE_CLASS, Names.LE, Primitive.LE, 1); - addAll(defs.DOUBLE_CLASS, Names.GT, Primitive.GT, 1); - addAll(defs.DOUBLE_CLASS, Names.GE, Primitive.GE, 1); - - // scala.Object - addPrimitive(defs.OBJECT_EQ, Primitive.ID); - addPrimitive(defs.OBJECT_NE, Primitive.NI); - addPrimitive(defs.OBJECT_SYNCHRONIZED, Primitive.SYNCHRONIZED); - - // scala.String - addPrimitive(defs.STRING_PLUS, Primitive.CONCAT); - - // scala.Throwable - addPrimitive(defs.THROWABLE_THROW, Primitive.THROW); - - // scala.Array - // !!! addAll(defs.ARRAY_CLASS, defs.EQEQ_N, Primitive.EQ, 1); - // !!! addAll(defs.ARRAY_CLASS, defs.BANGEQ_N, Primitive.NE, 1); - // !!! addAll(defs.ARRAY_CLASS, Names.equals, Primitive.EQUALS, 1); - // !!! addAll(defs.ARRAY_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - // !!! addAll(defs.ARRAY_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.ARRAY_CLASS, Names.length, Primitive.LENGTH, 1); - addAll(defs.ARRAY_CLASS, Names.apply, Primitive.APPLY, 1); - addAll(defs.ARRAY_CLASS, Names.update, Primitive.UPDATE, 1); - - // scala.runtime.RunTime - addPrimitive(BOX_UVALUE, Primitive.BOX); - addPrimitive(BOX_ZVALUE, Primitive.BOX); - addPrimitive(BOX_BVALUE, Primitive.BOX); - addPrimitive(BOX_SVALUE, Primitive.BOX); - addPrimitive(BOX_CVALUE, Primitive.BOX); - addPrimitive(BOX_IVALUE, Primitive.BOX); - addPrimitive(BOX_LVALUE, Primitive.BOX); - addPrimitive(BOX_FVALUE, Primitive.BOX); - addPrimitive(BOX_DVALUE, Primitive.BOX); - addPrimitive(BOX_ZARRAY, Primitive.BOX); - addPrimitive(BOX_BARRAY, Primitive.BOX); - addPrimitive(BOX_SARRAY, Primitive.BOX); - addPrimitive(BOX_CARRAY, Primitive.BOX); - addPrimitive(BOX_IARRAY, Primitive.BOX); - addPrimitive(BOX_LARRAY, Primitive.BOX); - addPrimitive(BOX_FARRAY, Primitive.BOX); - addPrimitive(BOX_DARRAY, Primitive.BOX); - addPrimitive(BOX_OARRAY, Primitive.BOX); - addPrimitive(BOX__ARRAY, Primitive.BOX); - addPrimitive(UNBOX_UVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_ZVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_BVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_SVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_CVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_IVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_LVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_FVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_DVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_ZARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_BARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_SARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_CARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_IARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_LARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_FARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_DARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_OARRAY, Primitive.UNBOX); - addPrimitive(UNBOX__ARRAY, Primitive.UNBOX); - addPrimitive(B2B, Primitive.B2B); - addPrimitive(B2S, Primitive.B2S); - addPrimitive(B2C, Primitive.B2C); - addPrimitive(B2I, Primitive.B2I); - addPrimitive(B2L, Primitive.B2L); - addPrimitive(B2F, Primitive.B2F); - addPrimitive(B2D, Primitive.B2D); - addPrimitive(S2B, Primitive.S2B); - addPrimitive(S2S, Primitive.S2S); - addPrimitive(S2C, Primitive.S2C); - addPrimitive(S2I, Primitive.S2I); - addPrimitive(S2L, Primitive.S2L); - addPrimitive(S2F, Primitive.S2F); - addPrimitive(S2D, Primitive.S2D); - addPrimitive(C2B, Primitive.C2B); - addPrimitive(C2S, Primitive.C2S); - addPrimitive(C2C, Primitive.C2C); - addPrimitive(C2I, Primitive.C2I); - addPrimitive(C2L, Primitive.C2L); - addPrimitive(C2F, Primitive.C2F); - addPrimitive(C2D, Primitive.C2D); - addPrimitive(I2B, Primitive.I2B); - addPrimitive(I2S, Primitive.I2S); - addPrimitive(I2C, Primitive.I2C); - addPrimitive(I2I, Primitive.I2I); - addPrimitive(I2L, Primitive.I2L); - addPrimitive(I2F, Primitive.I2F); - addPrimitive(I2D, Primitive.I2D); - addPrimitive(L2B, Primitive.L2B); - addPrimitive(L2S, Primitive.L2S); - addPrimitive(L2C, Primitive.L2C); - addPrimitive(L2I, Primitive.L2I); - addPrimitive(L2L, Primitive.L2L); - addPrimitive(L2F, Primitive.L2F); - addPrimitive(L2D, Primitive.L2D); - addPrimitive(F2B, Primitive.F2B); - addPrimitive(F2S, Primitive.F2S); - addPrimitive(F2C, Primitive.F2C); - addPrimitive(F2I, Primitive.F2I); - addPrimitive(F2L, Primitive.F2L); - addPrimitive(F2F, Primitive.F2F); - addPrimitive(F2D, Primitive.F2D); - addPrimitive(D2B, Primitive.D2B); - addPrimitive(D2S, Primitive.D2S); - addPrimitive(D2C, Primitive.D2C); - addPrimitive(D2I, Primitive.D2I); - addPrimitive(D2L, Primitive.D2L); - addPrimitive(D2F, Primitive.D2F); - addPrimitive(D2D, Primitive.D2D); - addPrimitive(NEW_ZARRAY, Primitive.NEW_ZARRAY); - addPrimitive(NEW_BARRAY, Primitive.NEW_BARRAY); - addPrimitive(NEW_SARRAY, Primitive.NEW_SARRAY); - addPrimitive(NEW_CARRAY, Primitive.NEW_CARRAY); - addPrimitive(NEW_IARRAY, Primitive.NEW_IARRAY); - addPrimitive(NEW_LARRAY, Primitive.NEW_LARRAY); - addPrimitive(NEW_FARRAY, Primitive.NEW_FARRAY); - addPrimitive(NEW_DARRAY, Primitive.NEW_DARRAY); - addPrimitive(NEW_OARRAY, Primitive.NEW_OARRAY); - addPrimitive(ZARRAY_LENGTH, Primitive.ZARRAY_LENGTH); - addPrimitive(BARRAY_LENGTH, Primitive.BARRAY_LENGTH); - addPrimitive(SARRAY_LENGTH, Primitive.SARRAY_LENGTH); - addPrimitive(CARRAY_LENGTH, Primitive.CARRAY_LENGTH); - addPrimitive(IARRAY_LENGTH, Primitive.IARRAY_LENGTH); - addPrimitive(LARRAY_LENGTH, Primitive.LARRAY_LENGTH); - addPrimitive(FARRAY_LENGTH, Primitive.FARRAY_LENGTH); - addPrimitive(DARRAY_LENGTH, Primitive.DARRAY_LENGTH); - addPrimitive(OARRAY_LENGTH, Primitive.OARRAY_LENGTH); - addPrimitive(ZARRAY_GET, Primitive.ZARRAY_GET); - addPrimitive(BARRAY_GET, Primitive.BARRAY_GET); - addPrimitive(SARRAY_GET, Primitive.SARRAY_GET); - addPrimitive(CARRAY_GET, Primitive.CARRAY_GET); - addPrimitive(IARRAY_GET, Primitive.IARRAY_GET); - addPrimitive(LARRAY_GET, Primitive.LARRAY_GET); - addPrimitive(FARRAY_GET, Primitive.FARRAY_GET); - addPrimitive(DARRAY_GET, Primitive.DARRAY_GET); - addPrimitive(OARRAY_GET, Primitive.OARRAY_GET); - addPrimitive(ZARRAY_SET, Primitive.ZARRAY_SET); - addPrimitive(BARRAY_SET, Primitive.BARRAY_SET); - addPrimitive(SARRAY_SET, Primitive.SARRAY_SET); - addPrimitive(CARRAY_SET, Primitive.CARRAY_SET); - addPrimitive(IARRAY_SET, Primitive.IARRAY_SET); - addPrimitive(LARRAY_SET, Primitive.LARRAY_SET); - addPrimitive(FARRAY_SET, Primitive.FARRAY_SET); - addPrimitive(DARRAY_SET, Primitive.DARRAY_SET); - addPrimitive(OARRAY_SET, Primitive.OARRAY_SET); - } - - private void addAdd(Symbol clasz, int count) { - Name name = Names.ADD; - Symbol symbol = clasz.lookup(name); - assert !symbol.isNone(): Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternativeSymbols(); - boolean unary = false; - boolean concat = false; - for (int i = 0; i < alts.length; i++) { - switch (alts[i].type()) { - case MethodType(Symbol[] vparams, _): - assert vparams.length == 1: alts[i].type(); - if (vparams[0].type().isSameAs(definitions.STRING_TYPE())) { - addPrimitive(alts[i], Primitive.CONCAT); - assert !concat; - concat = true; - } else { - addPrimitive(alts[i], Primitive.ADD); - count--; - } - break; - case PolyType(Symbol[] tparams, _): - addPrimitive(alts[i], Primitive.POS); - assert !unary; - unary = true; - break; - default: - throw Debug.abort("illegal case" , alts[i].type()); - } - } - assert count == 0 && unary && concat: count+" - "+unary+" - "+concat; - } - - private void addSub(Symbol clasz, int count) { - Name name = Names.SUB; - Symbol symbol = clasz.lookup(name); - assert !symbol.isNone(): Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternativeSymbols(); - boolean unary = false; - for (int i = 0; i < alts.length; i++) { - switch (alts[i].type()) { - case MethodType(_, _): - addPrimitive(alts[i], Primitive.SUB); - count--; - break; - case PolyType(_, _): - addPrimitive(alts[i], Primitive.NEG); - assert !unary; - unary = true; - break; - default: - throw Debug.abort("illegal case" , alts[i].type()); - } - } - assert count == 0 && unary: count + " - " + unary; - } - - private void addAll(Symbol clasz,Name name,Primitive primitive,int count) { - Symbol symbol = clasz.lookup(name); - assert symbol != Symbol.NONE : Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternativeSymbols(); - assert count == alts.length : count + " != " + alts.length; - for (int i = 0; i < alts.length; i++) addPrimitive(alts[i], primitive); - } - - private void addAllPrimitive(Symbol clasz, Name name, Primitive primitive, int count) { - Symbol symbol = clasz.lookup(name); - assert symbol != Symbol.NONE : Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternativeSymbols(); - int cnt = 0; - loop: - for (int i = 0; i < alts.length; i++) { - switch (alts[i].info()) { - case MethodType(Symbol[] vparams, _): - for (int j = 0; j < vparams.length; j++) { - if (!isValueType(vparams[j].info())) - continue loop; - } - addPrimitive(alts[i], primitive); - cnt++; - break; - } - } - assert cnt == count : "" + cnt + " != " + count; - } - - private boolean isValueType(Type t) { - return t.isSubType(definitions.ANYVAL_TYPE()); - } - - private void addPrimitive(Symbol symbol, Primitive primitive) { - assert !primitives.containsKey(symbol) : Debug.show(symbol); - primitives.put(symbol, primitive); - } - - //######################################################################## - // Primitives interface - general primitives - - /** Return true iff the given symbol refers to a primitive. */ - public boolean isPrimitive(Symbol symbol) { - return primitives.containsKey(symbol); - } - - /** Return primitive identified by the symbol. */ - public Primitive getPrimitive(Symbol symbol) { - Object value = primitives.get(symbol); - return value == null ? Primitive.NOT_A_PRIMITIVE : (Primitive)value; - } - - //######################################################################## - // Primitives interface - array creation primitives - - /** Return array creation method for elements of the given kind. */ - public Symbol getNewArraySymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return NEW_ZARRAY; - case TypeTags.BYTE : return NEW_BARRAY; - case TypeTags.SHORT : return NEW_SARRAY; - case TypeTags.CHAR : return NEW_CARRAY; - case TypeTags.INT : return NEW_IARRAY; - case TypeTags.LONG : return NEW_LARRAY; - case TypeTags.FLOAT : return NEW_FARRAY; - case TypeTags.DOUBLE : return NEW_DARRAY; - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Primitives interface - boxing primitives - - /** Return box method for values of the given type. */ - public Symbol getBoxValueSymbol(Type type) { - switch (type) { - case UnboxedType(int kind): - return getBoxValueSymbol(kind); - case UnboxedArrayType(Type elemtp): - return getBoxArraySymbol(elemtp); - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return box method for values of the given kind. */ - public Symbol getBoxValueSymbol(int kind) { - switch (kind) { - case TypeTags.UNIT : return BOX_UVALUE; - case TypeTags.BOOLEAN: return BOX_ZVALUE; - case TypeTags.BYTE : return BOX_BVALUE; - case TypeTags.SHORT : return BOX_SVALUE; - case TypeTags.CHAR : return BOX_CVALUE; - case TypeTags.INT : return BOX_IVALUE; - case TypeTags.LONG : return BOX_LVALUE; - case TypeTags.FLOAT : return BOX_FVALUE; - case TypeTags.DOUBLE : return BOX_DVALUE; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return box method for arrays of elements of the given type. */ - public Symbol getBoxArraySymbol(Type type) { - switch (type) { - case UnboxedType(int kind): - return getBoxArraySymbol(kind); - default: - return BOX_OARRAY; - } - } - - /** Return box method for arrays of elements of the given kind. */ - public Symbol getBoxArraySymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return BOX_ZARRAY; - case TypeTags.BYTE : return BOX_BARRAY; - case TypeTags.SHORT : return BOX_SARRAY; - case TypeTags.CHAR : return BOX_CARRAY; - case TypeTags.INT : return BOX_IARRAY; - case TypeTags.LONG : return BOX_LARRAY; - case TypeTags.FLOAT : return BOX_FARRAY; - case TypeTags.DOUBLE : return BOX_DARRAY; - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Primitives interface - unboxing primitives - - /** Return unbox method returning values of the given type. */ - public Symbol getUnboxValueSymbol(Type type) { - switch (type) { - case UnboxedType(int kind): - return getUnboxValueSymbol(kind); - case UnboxedArrayType(Type elemtp): - return getUnboxArraySymbol(elemtp); - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return unbox method returning values of the given kind. */ - public Symbol getUnboxValueSymbol(int kind) { - switch (kind) { - case TypeTags.UNIT : return UNBOX_UVALUE; - case TypeTags.BOOLEAN: return UNBOX_ZVALUE; - case TypeTags.BYTE : return UNBOX_BVALUE; - case TypeTags.SHORT : return UNBOX_SVALUE; - case TypeTags.CHAR : return UNBOX_CVALUE; - case TypeTags.INT : return UNBOX_IVALUE; - case TypeTags.LONG : return UNBOX_LVALUE; - case TypeTags.FLOAT : return UNBOX_FVALUE; - case TypeTags.DOUBLE : return UNBOX_DVALUE; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return unbox method returning arrays of elements of the given type. */ - public Symbol getUnboxArraySymbol(Type type) { - switch (type) { - case UnboxedType(int kind): - return getUnboxArraySymbol(kind); - default: - return UNBOX_OARRAY; - } - } - - /** Return unbox method returning arrays of elements of the given kind. */ - public Symbol getUnboxArraySymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return UNBOX_ZARRAY; - case TypeTags.BYTE : return UNBOX_BARRAY; - case TypeTags.SHORT : return UNBOX_SARRAY; - case TypeTags.CHAR : return UNBOX_CARRAY; - case TypeTags.INT : return UNBOX_IARRAY; - case TypeTags.LONG : return UNBOX_LARRAY; - case TypeTags.FLOAT : return UNBOX_FARRAY; - case TypeTags.DOUBLE : return UNBOX_DARRAY; - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Primitives interface - conversion primitives - - /** Return conversion method for given types. */ - public Symbol getConvertSymbol(Type from, Type to) { - switch (from) { - case UnboxedType(int kind): - return getConvertSymbol(kind, to); - default: - throw Debug.abort("illegal case", from); - } - } - - /** Return conversion method for given type and type kind. */ - public Symbol getConvertSymbol(Type from, int to) { - switch (from) { - case UnboxedType(int kind): - return getConvertSymbol(kind, to); - default: - throw Debug.abort("illegal case", from); - } - } - - /** Return conversion method for given type kind and type. */ - public Symbol getConvertSymbol(int from, Type to) { - switch (to) { - case UnboxedType(int kind): - return getConvertSymbol(from, kind); - default: - throw Debug.abort("illegal case", to); - } - } - - /** Return conversion method for given kind types. */ - public Symbol getConvertSymbol(int from, int to) { - switch (from) { - case TypeTags.BYTE : - switch (to) { - case TypeTags.BYTE : return B2B; - case TypeTags.SHORT : return B2S; - case TypeTags.CHAR : return B2C; - case TypeTags.INT : return B2I; - case TypeTags.LONG : return B2L; - case TypeTags.FLOAT : return B2F; - case TypeTags.DOUBLE : return B2D; - } break; - case TypeTags.SHORT : - switch (to) { - case TypeTags.BYTE : return S2B; - case TypeTags.SHORT : return S2S; - case TypeTags.CHAR : return S2C; - case TypeTags.INT : return S2I; - case TypeTags.LONG : return S2L; - case TypeTags.FLOAT : return S2F; - case TypeTags.DOUBLE : return S2D; - } break; - case TypeTags.CHAR : - switch (to) { - case TypeTags.BYTE : return C2B; - case TypeTags.SHORT : return C2S; - case TypeTags.CHAR : return C2C; - case TypeTags.INT : return C2I; - case TypeTags.LONG : return C2L; - case TypeTags.FLOAT : return C2F; - case TypeTags.DOUBLE : return C2D; - } break; - case TypeTags.INT : - switch (to) { - case TypeTags.BYTE : return I2B; - case TypeTags.SHORT : return I2S; - case TypeTags.CHAR : return I2C; - case TypeTags.INT : return I2I; - case TypeTags.LONG : return I2L; - case TypeTags.FLOAT : return I2F; - case TypeTags.DOUBLE : return I2D; - } break; - case TypeTags.LONG : - switch (to) { - case TypeTags.BYTE : return L2B; - case TypeTags.SHORT : return L2S; - case TypeTags.CHAR : return L2C; - case TypeTags.INT : return L2I; - case TypeTags.LONG : return L2L; - case TypeTags.FLOAT : return L2F; - case TypeTags.DOUBLE : return L2D; - } break; - case TypeTags.FLOAT : - switch (to) { - case TypeTags.BYTE : return F2B; - case TypeTags.SHORT : return F2S; - case TypeTags.CHAR : return F2C; - case TypeTags.INT : return F2I; - case TypeTags.LONG : return F2L; - case TypeTags.FLOAT : return F2F; - case TypeTags.DOUBLE : return F2D; - } break; - case TypeTags.DOUBLE : - switch (to) { - case TypeTags.BYTE : return D2B; - case TypeTags.SHORT : return D2S; - case TypeTags.CHAR : return D2C; - case TypeTags.INT : return D2I; - case TypeTags.LONG : return D2L; - case TypeTags.FLOAT : return D2F; - case TypeTags.DOUBLE : return D2D; - } break; - } - throw Debug.abort("illegal case: " + from + " -> " + to); - } - - //######################################################################## - // Primitives interface - array get and set primitives - - /** Return length method for arrays of the given type. */ - public Symbol getArrayLengthSymbol(Type type) { - switch (type) { - case UnboxedArrayType(UnboxedType(int kind)): - return getArrayLengthSymbol(kind); - case UnboxedArrayType(_): - return OARRAY_LENGTH; - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return length method for arrays of elements of the given kind. */ - public Symbol getArrayLengthSymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return ZARRAY_LENGTH; - case TypeTags.BYTE : return BARRAY_LENGTH; - case TypeTags.SHORT : return SARRAY_LENGTH; - case TypeTags.CHAR : return CARRAY_LENGTH; - case TypeTags.INT : return IARRAY_LENGTH; - case TypeTags.LONG : return LARRAY_LENGTH; - case TypeTags.FLOAT : return FARRAY_LENGTH; - case TypeTags.DOUBLE : return DARRAY_LENGTH; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return get method for arrays of the given type. */ - public Symbol getArrayGetSymbol(Type type) { - switch (type) { - case UnboxedArrayType(UnboxedType(int kind)): - return getArrayGetSymbol(kind); - case UnboxedArrayType(_): - return OARRAY_GET; - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return get method for arrays of elements of the given kind. */ - public Symbol getArrayGetSymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return ZARRAY_GET; - case TypeTags.BYTE : return BARRAY_GET; - case TypeTags.SHORT : return SARRAY_GET; - case TypeTags.CHAR : return CARRAY_GET; - case TypeTags.INT : return IARRAY_GET; - case TypeTags.LONG : return LARRAY_GET; - case TypeTags.FLOAT : return FARRAY_GET; - case TypeTags.DOUBLE : return DARRAY_GET; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return set method for arrays of the given type. */ - public Symbol getArraySetSymbol(Type type) { - switch (type) { - case UnboxedArrayType(UnboxedType(int kind)): - return getArraySetSymbol(kind); - case UnboxedArrayType(_): - return OARRAY_SET; - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return set method for arrays of elements of the given kind. */ - public Symbol getArraySetSymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return ZARRAY_SET; - case TypeTags.BYTE : return BARRAY_SET; - case TypeTags.SHORT : return SARRAY_SET; - case TypeTags.CHAR : return CARRAY_SET; - case TypeTags.INT : return IARRAY_SET; - case TypeTags.LONG : return LARRAY_SET; - case TypeTags.FLOAT : return FARRAY_SET; - case TypeTags.DOUBLE : return DARRAY_SET; - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Primitives interface - class names - - /* Return name to use in "Class.forName(<name>)" for the given type. */ - public String getNameForClassForName(Type type) { - switch (type) { - case TypeRef(_, Symbol symbol, _): - return getNameForClassForName(symbol); - case UnboxedType(int kind): - return getNameForClassForName(kind); - case UnboxedArrayType(TypeRef(_, Symbol symbol, _)): - return "[L" + getNameForClassForName(symbol) + ";"; - case UnboxedArrayType(Type elemtp): - return "[" + getNameForClassForName(elemtp); - default: - throw Debug.abort("illegal case", type); - } - } - - /* Return name to use in "Class.forName(<name>)" for the given symbol. */ - public String getNameForClassForName(Symbol symbol) { - return getJREClassName(symbol); - } - - /* Return name to use in "Class.forName(<name>)" for the given kind. */ - public String getNameForClassForName(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return "Z"; - case TypeTags.BYTE : return "B"; - case TypeTags.SHORT : return "S"; - case TypeTags.CHAR : return "C"; - case TypeTags.INT : return "I"; - case TypeTags.LONG : return "J"; - case TypeTags.FLOAT : return "F"; - case TypeTags.DOUBLE : return "D"; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return the JRE name of given class. */ - public String getJREClassName(Symbol clasz) { - assert clasz.isClassType(): Debug.show(clasz); - if (clasz == definitions.ANY_CLASS || - clasz == definitions.ANYREF_CLASS) - return getJREClassName(definitions.OBJECT_CLASS); - String suffix = clasz.isModuleClass() && !clasz.isJava() ? "$" : ""; - return jreNameWriter.toString(clasz, suffix); - } - - /** Return the CLR name of given class. */ - public String getCLRClassName(Symbol clasz) { - assert clasz.isClassType(): Debug.show(clasz); - return clrNameWriter.toString(clasz); - } - - //######################################################################## -} diff --git a/sources/scalac/backend/jvm/GenJVM.java b/sources/scalac/backend/jvm/GenJVM.java deleted file mode 100644 index 3ea0cded19..0000000000 --- a/sources/scalac/backend/jvm/GenJVM.java +++ /dev/null @@ -1,1927 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.backend.jvm; - -import java.io.*; -import java.nio.ByteBuffer; -import java.util.*; - -import ch.epfl.lamp.fjbg.*; -import ch.epfl.lamp.util.Pair; - -import scala.tools.util.Position; - -import scalac.*; -import scalac.ast.Tree; -import scalac.atree.AConstant; -import scalac.backend.*; -import scalac.symtab.*; -import scalac.symtab.classfile.ClassfileConstants; -import scalac.symtab.classfile.Pickle; -import scalac.transformer.*; -import scalac.util.*; - - -/* Several things which are done here should in fact be done in - * previous phases, namely: - * - * - code linearisation (i.e. representation of code as a list of - * instructions), - * - * - removal of implicit "this" selection, - * - * - removal of implicit "unit" values, - * - * - removal of implicit conversion, - * - * - removal of "if"s without explicit "else" part, - * - * - expansion of "==", - * - * - introduction of a special primitive for string concatenation, - * - * - initialisation of module instance variable. - */ - -/** - * Backend generating JVM byte-codes. - * - * @version 2.0 - * @author Michel Schinz - */ - -public class GenJVM { - protected final static String JAVA_LANG_OBJECT = "java.lang.Object"; - protected final static String JAVA_LANG_STRING = "java.lang.String"; - protected final static String JAVA_LANG_STRINGBUFFER = - "java.lang.StringBuffer"; - protected final static String JAVA_RMI_REMOTE = "java.rmi.Remote"; - protected final static String JAVA_RMI_REMOTEEXCEPTION = - "java.rmi.RemoteException"; - - protected final static String SCALA_RUNTIME_RUNTIME = - "scala.runtime.RunTime"; - - protected final static String SCALA_ATTR = - ClassfileConstants.SCALA_N.toString(); - - protected final static String MODULE_INSTANCE_FIELD_NAME = "MODULE$"; - - protected final static String CONSTRUCTOR_STRING = - "<init>"; // TODO get it from FJBG - - protected final JObjectType JAVA_LANG_OBJECT_T = - new JObjectType(JAVA_LANG_OBJECT); - protected final JObjectType JAVA_LANG_STRING_T = - new JObjectType(JAVA_LANG_STRING); - protected final JObjectType JAVA_LANG_STRINGBUFFER_T = - new JObjectType (JAVA_LANG_STRINGBUFFER); - protected final JObjectType JAVA_LANG_THROWABLE_T = - new JObjectType("java.lang.Throwable"); - - protected final Symbol JAVA_RMI_REMOTE_CLASS; - protected final Symbol SCALA_SERIAL_VERSION_UID_CONSTR; - - protected final Global global; - protected final Definitions defs; - protected final Primitives prims; - - protected final Phase refCheckPhase; - protected final AddInterfacesPhase addInterfacesPhase; - - protected final FJBGContext fjbgContext; - - protected final ArrayList pickles = new ArrayList(); - - public GenJVM(Global global) { - this.global = global; - this.defs = global.definitions; - this.prims = global.primitives; - - this.refCheckPhase = global.PHASE.REFCHECK.phase(); - this.addInterfacesPhase = - (AddInterfacesPhase)global.PHASE.ADDINTERFACES.phase(); - - this.fjbgContext = new FJBGContext(); - - initTypeMap(); - initArithPrimMap(); - - JAVA_RMI_REMOTE_CLASS = defs.getClass(JAVA_RMI_REMOTE); - SCALA_SERIAL_VERSION_UID_CONSTR = - defs.getClass("scala.SerialVersionUID") .primaryConstructor(); - } - - /// Code generation - ////////////////////////////////////////////////////////////////////// - - /** Generate code for the given units. */ - public static void translate(Global global, CompilationUnit[] units) { - GenJVM translator = new GenJVM(global); - for (int i = 0; i < units.length; i++) translator.translate(units[i]); - } - - /** - * Generate code for the given unit. - */ - public void translate(CompilationUnit unit) { - try { - for (int i = 0; i < unit.body.length; ++i) - gen(Context.EMPTY.withSourceFileName(unit.source.getFile().getName()), - unit.body[i]); - } catch (JCode.OffsetTooBigException e) { - if (global.debug) e.printStackTrace(); - global.error(e.getMessage()); - } - // write .symbl files (must be generated after .class files) - for (int i = 0; i < pickles.size() / 2; i++) { - JClass clazz = (JClass)pickles.get(2 * i + 0); - Pickle pickle = (Pickle)pickles.get(2 * i + 1); - writeSymblFile(clazz, pickle); - } - pickles.clear(); - } - - /** - * Generate code to perform the side effects associated with the - * given tree (i.e. no value should remain on the stack - * afterwards). - */ - protected void gen(Context ctx, Tree tree) throws JCode.OffsetTooBigException { - startCodeForTree(ctx, tree); - - Symbol sym = tree.symbol(); - - switch (tree) { - case PackageDef(_, Tree.Template impl): - gen(ctx, impl); - break; - - case ClassDef(_, _, _, _, _, Tree.Template impl) : { - Tree.ClassDef classDef = (Tree.ClassDef)tree; - - Context ctx1 = enterClass(ctx, sym); - - addValueClassMembers(ctx1, classDef); - gen(ctx1, impl); - AConstant[] aargs = global.getAttrArguments - (sym, SCALA_SERIAL_VERSION_UID_CONSTR); - if (ctx1.isModuleClass || aargs != null) { - JMethod clinit = getClassConstructorMethod(ctx1); - if (clinit.getCode().getSize() == 0) { - Context ctx2 = - ctx1.withMethod(clinit, Collections.EMPTY_MAP, false); - completeClassConstructor(ctx2, sym); - ctx2.code.emitRETURN(); - genLocalVariableTable(ctx2); - } - } - - leaveClass(ctx1, sym); - } break; - - case Template(_, Tree[] body): - gen(ctx, body); - break; - - case ValDef(_, Name name, _, Tree rhs): { - if (ctx.method == null) - break; // ignore ValDefs in classes, handled elsewhere - - JType valType = typeStoJ(sym.info()); - JLocalVariable var = - ctx.method.addNewLocalVariable(valType, name.toString()); - ctx.locals.put(sym, new Integer(var.getIndex())); - - assert (rhs != Tree.Empty) : Debug.show(sym); - genLoad(ctx, rhs, valType); - ctx.code.emitSTORE(var); - } break; - - case DefDef(_, _, _, _, _, Tree rhs): { - Tree.DefDef defDef = (Tree.DefDef)tree; - boolean retry = false; - do { - Context ctx1 = enterMethod(ctx, defDef, retry); - try { - if (! Modifiers.Helper.isAbstract(sym.flags)) { - JType retType = ctx1.method.getReturnType(); - genLoad(ctx1, rhs, retType); - if (sym.name == Names.CLASS_CONSTRUCTOR) - completeClassConstructor(ctx1, sym.owner()); - ctx1.code.emitRETURN(retType); - ctx1.method.freeze(); - } - leaveMethod(ctx1); - break; - } catch (JCode.OffsetTooBigException e) { - ctx1.clazz.removeMethod(ctx1.method); - if (retry) - throw Debug.abort("method too big", sym, e); - retry = true; - } - } while (retry); - } break; - - case Return(Tree expr): { - JType retType = ctx.method.getReturnType(); - genLoad(ctx, expr, retType); - ctx.code.emitRETURN(retType); - } break; - - case Typed(Tree expr, _): - gen(ctx, expr); - break; - - case Empty: - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case TypeApply(_, _): - case FunType(_, _): - case CompoundType(_, _): - case AppliedType(_,_): - break; - - default: - genLoad(ctx, tree, JType.VOID); - } - - endCodeForTree(ctx, tree); - } - - protected void gen(Context ctx, Tree[] trees) - throws JCode.OffsetTooBigException { - for (int i = 0; i < trees.length; ++i) - gen(ctx, trees[i]); - } - - /** - * Generate code to load the value of the given tree on the - * stack, and make sure it is of the given expected type. - */ - protected JType genLoad(Context ctx, Tree tree, JType expectedType) - throws JCode.OffsetTooBigException { - startCodeForTree(ctx, tree); - - JType generatedType = null; - Symbol sym = tree.symbol(); - - switch (tree) { - case LabelDef(_, Tree.Ident[] params, Tree rhs): { - JCode.Label label = ctx.code.newLabel(); - label.anchorToNext(); - ctx.labels.put(sym, new Pair(label, params)); - generatedType = genLoad(ctx, rhs, expectedType); - ctx.labels.remove(sym); - } break; - - case Block(Tree[] stats, Tree value): { - int statsNum = stats.length; - for (int i = 0; i < stats.length; ++i) - gen(ctx, stats[i]); - genLoad(ctx, value, expectedType); - generatedType = expectedType; - } break; - - case Typed(Tree expr, _): - genLoad(ctx, expr, expectedType); - generatedType = expectedType; - break; - - case New(Tree init): - String className = javaName(tree.type.symbol()); - ctx.code.emitNEW(className); - ctx.code.emitDUP(); - gen(ctx, init); - generatedType = new JObjectType(className); - break; - - case Apply(TypeApply(Tree fun, Tree[] args), _): { - genLoadQualifier(ctx, fun); - - JType type = typeStoJ(args[0].type); - if (fun.symbol() == defs.ANY_IS_ERASED) { - ctx.code.emitINSTANCEOF((JReferenceType)type); - generatedType = JType.BOOLEAN; - } else if (fun.symbol() == defs.ANY_AS_ERASED) { - ctx.code.emitCHECKCAST((JReferenceType)type); - generatedType = type; - } else - throw Debug.abort("unexpected type application", tree); - } break; - - case Apply(Tree fun, Tree[] args): { - Symbol funSym = fun.symbol(); - - if (funSym.isLabel()) { - Pair/*<Label, Tree[]>*/ labelAndIdents = - (Pair)ctx.labels.get(funSym); - assert labelAndIdents != null : Debug.show(funSym); - JMethodType funType = (JMethodType)typeStoJ(funSym.info()); - - JCode.Label label = (JCode.Label)labelAndIdents.fst; - Tree[] idents = (Tree[])labelAndIdents.snd; - assert idents.length == args.length; - - for (int i = 0; i < args.length; ++i) - genLoad(ctx, args[i], typeStoJ(args[i].type)); - for (int i = idents.length; i > 0; --i) - genStoreEpilogue(ctx, idents[i-1]); - ctx.code.emitGOTO_maybe_W(label, ctx.useWideJumps); - generatedType = funType.getReturnType(); - } else if (isKnownPrimitive(funSym)) { - Primitive prim = prims.getPrimitive(funSym); - - switch (prim) { - case CONCAT: - genStringConcatenation(ctx, liftStringConcatenations(tree)); - generatedType = JAVA_LANG_STRING_T; - break; - - case POS: case NEG: - case ADD: case SUB: case MUL: case DIV: case MOD: - case NOT: case OR : case XOR: case AND: - case LSL: case LSR: case ASR: - Tree[] allArgs = extractPrimitiveArgs((Tree.Apply)tree); - allArgs[0] = unbox(allArgs[0]); - JType resType = typeStoJ(tree.type); - genArithPrim(ctx, prim, allArgs, resType, expectedType); - generatedType = resType; - break; - - case ID: case NI: - case EQ: case NE: case LT: case LE: case GE: case GT: - case ZNOT: case ZOR: case ZAND: - JCode.Label falseLabel = ctx.code.newLabel(); - JCode.Label afterLabel = ctx.code.newLabel(); - genCond(ctx, tree, falseLabel, false); - ctx.code.emitICONST_1(); - ctx.code.emitGOTO_maybe_W(afterLabel, ctx.useWideJumps); - falseLabel.anchorToNext(); - ctx.code.emitICONST_0(); - afterLabel.anchorToNext(); - generatedType = JType.BOOLEAN; - break; - - case THROW: - assert args.length == 0; - genThrow(ctx, ((Tree.Select)fun).qualifier); - // We pretend that we generated something of the - // expected type, to avoid trying to generate - // bogus conversions. - generatedType = expectedType; - break; - - case SYNCHRONIZED: { - assert args.length == 1; - Tree qual = ((Tree.Select)fun).qualifier; - genSynchronized(ctx, qual, args[0], expectedType); - generatedType = expectedType; - } break; - - case NEW_OARRAY: { - assert args.length == 2; - genRefArrayCreate(ctx, args[0], args[1]); - generatedType = expectedType; - } break; - - case NEW_ZARRAY : case NEW_BARRAY : case NEW_SARRAY : - case NEW_CARRAY : case NEW_IARRAY : case NEW_LARRAY : - case NEW_FARRAY : case NEW_DARRAY : - assert args.length == 1; - genArrayCreate(ctx, prim, args[0]); - generatedType = JAVA_LANG_OBJECT_T; // TODO refine - break; - - case ZARRAY_SET : case BARRAY_SET : case SARRAY_SET : - case CARRAY_SET : case IARRAY_SET : case LARRAY_SET : - case FARRAY_SET : case DARRAY_SET : case OARRAY_SET : - assert args.length == 3; - genArrayUpdate(ctx, args[0], args[1], args[2]); - generatedType = JType.VOID; - break; - - case ZARRAY_GET : case BARRAY_GET : case SARRAY_GET : - case CARRAY_GET : case IARRAY_GET : case LARRAY_GET : - case FARRAY_GET : case DARRAY_GET : case OARRAY_GET : - assert args.length == 2 : "get - " + args.length; - genArrayAccess(ctx, args[0], args[1]); - generatedType = getArrayElementType(args[0]); - break; - - case ZARRAY_LENGTH : case BARRAY_LENGTH : case SARRAY_LENGTH : - case CARRAY_LENGTH : case IARRAY_LENGTH : case LARRAY_LENGTH : - case FARRAY_LENGTH : case DARRAY_LENGTH : case OARRAY_LENGTH : - assert args.length == 1 : args.length; - genArrayLength(ctx, args[0]); - generatedType = JType.INT; - break; - - case B2B: case B2S: case B2C: case B2I: case B2L: case B2F: case B2D: - case S2B: case S2S: case S2C: case S2I: case S2L: case S2F: case S2D: - case C2B: case C2S: case C2C: case C2I: case C2L: case C2F: case C2D: - case I2B: case I2S: case I2C: case I2I: case I2L: case I2F: case I2D: - case L2B: case L2S: case L2C: case L2I: case L2L: case L2F: case L2D: - case F2B: case F2S: case F2C: case F2I: case F2L: case F2F: case F2D: - case D2B: case D2S: case D2C: case D2I: case D2L: case D2F: case D2D: - assert args.length == 1 : args.length; - JType fromType = typeStoJ(args[0].type); - genLoad(ctx, args[0], fromType); - ctx.code.emitT2T(fromType, expectedType); - generatedType = expectedType; - break; - - default: - throw Debug.abort("unknown primitive", prim); - } - } else { - JMethodType funType = (JMethodType)typeStoJ(funSym.info()); - JType[] argTypes = funType.getArgumentTypes(); - - boolean isConstrCall = funSym.isInitializer(); - boolean isSuperCall = false; - switch (fun) { - case Select(Super(_, _), _): isSuperCall = true; - } - - boolean isStatic = isStaticMember(funSym); - if (!isStatic) - genLoadQualifier(ctx, fun); - for (int i = 0; i < args.length; ++i) - genLoad(ctx, args[i], argTypes[i]); - - String clsName = isSuperCall - ? ctx.clazz.getSuperclassName() - : javaName(funSym.owner()); - String mthName = funSym.name.toString(); - - funSym.owner().info(); // [HACK] ensure that flags are - // transformed. - - if (funSym.owner().isInterface()) - ctx.code.emitINVOKEINTERFACE(clsName, mthName, funType); - else { - if (isConstrCall || isSuperCall) { - ctx.code.emitINVOKESPECIAL(clsName, mthName, funType); - if (isConstrCall && isSuperCall && ctx.isModuleClass) { - // Initialise module instance field ASAP - ctx.code.emitALOAD_0(); - ctx.code.emitPUTSTATIC(ctx.clazz.getName(), - MODULE_INSTANCE_FIELD_NAME, - ctx.clazz.getType()); - } - } else if (isStatic) - ctx.code.emitINVOKESTATIC(clsName, mthName, funType); - else - ctx.code.emitINVOKEVIRTUAL(clsName, mthName, funType); - } - generatedType = funType.getReturnType(); - } - } break; - - case Ident(_): - JType type = typeStoJ(sym.info()); - if (sym.isModule()) { - String javaSymName = javaName(sym.moduleClass()); - ctx.code.emitGETSTATIC(javaSymName, - MODULE_INSTANCE_FIELD_NAME, - type); - generatedType = type; - } else if (sym.isStatic()) { - JType fieldType = typeStoJ(sym.info()); - String className = javaName(sym.owner()); - String fieldName = sym.name.toString(); - ctx.code.emitGETSTATIC(className, fieldName, fieldType); - generatedType = type; - } else { - assert ctx.locals.containsKey(sym) - : Debug.show(sym) + " not in " + ctx.locals; - int index = ((Integer)(ctx.locals.get(sym))).intValue(); - ctx.code.emitLOAD(index, type); - generatedType = type; - } - break; - - case Select(Tree qualifier, _): - JType fieldType = typeStoJ(sym.info()); - String className = javaName(sym.owner()); - String fieldName = sym.name.toString(); - if (sym.isStatic()) { - ctx.code.emitGETSTATIC(className, fieldName, fieldType); - } else { - genLoadQualifier(ctx, tree); - ctx.code.emitGETFIELD(className, fieldName, fieldType); - } - generatedType = fieldType; - break; - - case Assign(Tree lhs, Tree rhs): { - genStorePrologue(ctx, lhs); - genLoad(ctx, rhs, typeStoJ(lhs.symbol().info())); - genStoreEpilogue(ctx, lhs); - generatedType = JType.VOID; - } break; - - case If(Tree cond, Tree thenp, Tree elsep): { - JType finalType = typeStoJ(tree.type); - - JCode.Label elseLabel = ctx.code.newLabel(); - genCond(ctx, cond, elseLabel, false); - genLoad(ctx, thenp, finalType); - JCode.Label afterLabel = ctx.code.newLabel(); - ctx.code.emitGOTO_maybe_W(afterLabel, ctx.useWideJumps); - elseLabel.anchorToNext(); - genLoad(ctx, elsep, finalType); - afterLabel.anchorToNext(); - generatedType = finalType; - } break; - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): { - JCode.Label[] labels = ctx.code.newLabels(bodies.length); - JCode.Label defaultLabel = ctx.code.newLabel(); - JCode.Label afterLabel = ctx.code.newLabel(); - - genLoad(ctx, test, JType.INT); - ctx.code.emitSWITCH(tags, labels, defaultLabel, 0.9); - for (int i = 0; i < bodies.length; ++i) { - labels[i].anchorToNext(); - genLoad(ctx, bodies[i], expectedType); - ctx.code.emitGOTO_maybe_W(afterLabel, ctx.useWideJumps); - } - defaultLabel.anchorToNext(); - genLoad(ctx, otherwise, expectedType); - afterLabel.anchorToNext(); - generatedType = expectedType; - } break; - - case This(_): - case Super(_, _): - ctx.code.emitALOAD_0(); - generatedType = JAVA_LANG_OBJECT_T; - break; - - case Literal(AConstant value): - generatedType = genLoadLiteral(ctx, value, expectedType); - break; - - case Empty: - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case TypeApply(_, _): - case FunType(_, _): - case CompoundType(_, _): - case AppliedType(_,_): - generatedType = JType.VOID; - break; - - case Sequence(_): - case ModuleDef(_,_,_,_): - case PatDef(_,_,_): - case Import(_, _): - case CaseDef(_, _, _): - case Visitor(_): - case Function(_, _): - throw Debug.abort("unexpected node", tree); - default: - throw Debug.abort("unknown node", tree); - } - - // Pop unneeded result from stack, or widen it if needed. - if (expectedType == JType.VOID && generatedType != JType.VOID) { - if (generatedType == JType.LONG || generatedType == JType.DOUBLE) - ctx.code.emitPOP2(); - else - ctx.code.emitPOP(); - } else if (! (expectedType == JType.VOID - || generatedType == expectedType - || generatedType.isReferenceType())) - ctx.code.emitT2T(generatedType, expectedType); - - endCodeForTree(ctx, tree); - return expectedType; - } - - /** - * Generate code to load the qualifier of the given tree, which - * can be implicitely "this". - */ - protected void genLoadQualifier(Context ctx, Tree tree) - throws JCode.OffsetTooBigException { - switch (tree) { - case Ident(_): - break; - case Select(Create(_, _), _): - break; - case Select(Tree qualifier, _): - genLoad(ctx, qualifier, JAVA_LANG_OBJECT_T); - break; - default: - throw Debug.abort("unknown qualifier", tree); - } - } - - protected JType genLoadLiteral(Context ctx, AConstant lit, JType type) { - switch (lit) { - case UNIT: - return JType.VOID; - case BOOLEAN(boolean value): - ctx.code.emitPUSH(value); - return JType.BOOLEAN; - case BYTE(byte value): - ctx.code.emitPUSH(value); - return JType.BYTE; - case SHORT(short value): - ctx.code.emitPUSH(value); - return JType.SHORT; - case CHAR(char value): - ctx.code.emitPUSH(value); - return JType.CHAR; - case INT(int value): - ctx.code.emitPUSH(value); - return JType.INT; - case LONG(long value): - ctx.code.emitPUSH(value); - return JType.LONG; - case FLOAT(float value): - ctx.code.emitPUSH(value); - return JType.FLOAT; - case DOUBLE(double value): - ctx.code.emitPUSH(value); - return JType.DOUBLE; - case STRING(String value): - ctx.code.emitPUSH(value); - return JAVA_LANG_STRING_T; - case SYMBOL_NAME(Symbol value): - ctx.code.emitPUSH(javaName(value)); - return JAVA_LANG_STRING_T; - case NULL: - if (type != JType.VOID) ctx.code.emitACONST_NULL(); - return type; - default: - throw Debug.abort("unknown literal", lit); - } - } - - /** - * Generate code to prepare the storage of a value in the location - * represented by the tree. - */ - protected void genStorePrologue(Context ctx, Tree tree) - throws JCode.OffsetTooBigException { - genLoadQualifier(ctx, tree); - } - - /** - * Generate code to perform the storage of the value on top of - * stack in the location represented by the tree. - */ - protected void genStoreEpilogue(Context ctx, Tree tree) { - Symbol sym = tree.symbol(); - if (sym.owner().isClass()) { - String ownerName = javaName(sym.owner()); - if (isStaticMember(sym)) - ctx.code.emitPUTSTATIC(ownerName, - sym.name.toString(), - typeStoJ(sym.info())); - else - ctx.code.emitPUTFIELD(ownerName, - sym.name.toString(), - typeStoJ(sym.info())); - } else { - assert ctx.locals.containsKey(sym) - : Debug.show(sym) + " not in " + ctx.locals; - int index = ((Integer)(ctx.locals.get(sym))).intValue(); - ctx.code.emitSTORE(index, typeStoJ(sym.info())); - } - } - - /** - * Generate code to evaluate the condition associated with the - * given tree and jump to the target when the condition is equal - * to the given value. - */ - protected void genCond(Context ctx, - Tree tree, - JCode.Label target, - boolean when) - throws JCode.OffsetTooBigException { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (isJumpingPrimitive(fun.symbol())) { - Primitive prim = prims.getPrimitive(fun.symbol()); - Tree[] allArgs = extractPrimitiveArgs((Tree.Apply)tree); - - switch (prim) { - case ID: case NI: case EQ: case NE: - assert allArgs.length == 2; - Tree unbox1 = unbox(allArgs[0]); - Tree unbox2 = unbox(allArgs[1]); - if (!getMaxType(unbox1, unbox2).isReferenceType()) { - allArgs[0] = unbox1; - allArgs[1] = unbox2; - genCompPrim(ctx, prim, allArgs, target, when); - } else { - genEqPrim(ctx, prim, allArgs, target, when); - } - return; - - case LT: case LE: case GE: case GT: - assert allArgs.length == 2; - allArgs[0] = unbox(allArgs[0]); - genCompPrim(ctx, prim, allArgs, target, when); - return; - - case ZNOT: - assert allArgs.length == 1; - genCond(ctx, unbox(allArgs[0]), target, !when); - return; - - case ZOR: - case ZAND: - if (when ^ (prim == Primitive.ZAND)) { - // x || y jump if true -or- x && y jump if false - genCond(ctx, unbox(allArgs[0]), target, when); - genCond(ctx, allArgs[1], target, when); - } else { - // x || y jump if false -or- x && y jump if true - JCode.Label afterLabel = ctx.code.newLabel(); - genCond(ctx, unbox(allArgs[0]), afterLabel, !when); - genCond(ctx, allArgs[1], target, when); - afterLabel.anchorToNext(); - } - return; - } - } - } - // Default case: the condition is not a comparison or logical - // primitive. - genLoad(ctx, tree, JType.BOOLEAN); - if (when) - ctx.code.emitIFNE(target); - else - ctx.code.emitIFEQ(target); - } - - protected Map/*<Primitive, Instruction>*/ arithPrimMap; - protected void addPrim(Primitive prim, - JOpcode z, - JOpcode i, - JOpcode l, - JOpcode f, - JOpcode d) { - arithPrimMap.put(prim, new JOpcode[] { z, i, l, f, d }); - } - - protected void initArithPrimMap() { - arithPrimMap = new HashMap(); - /* boolean, int & al., long, float, double */ - addPrim(Primitive.ADD, - null, JOpcode.IADD, JOpcode.LADD, JOpcode.FADD, JOpcode.DADD); - addPrim(Primitive.SUB, - null, JOpcode.ISUB, JOpcode.LSUB, JOpcode.FSUB, JOpcode.DSUB); - addPrim(Primitive.MUL, - null, JOpcode.IMUL, JOpcode.LMUL, JOpcode.FMUL, JOpcode.DMUL); - addPrim(Primitive.DIV, - null, JOpcode.IDIV, JOpcode.LDIV, JOpcode.FDIV, JOpcode.DDIV); - addPrim(Primitive.MOD, - null, JOpcode.IREM, JOpcode.LREM, JOpcode.FREM, JOpcode.DREM); - addPrim(Primitive.AND, - JOpcode.IAND, JOpcode.IAND, JOpcode.LAND, null, null); - addPrim(Primitive.OR, - JOpcode.IOR, JOpcode.IOR, JOpcode.LOR, null, null); - addPrim(Primitive.XOR, - JOpcode.IXOR, JOpcode.IXOR, JOpcode.LXOR, null, null); - addPrim(Primitive.LSL, - null, JOpcode.ISHL, JOpcode.LSHL, null, null); - addPrim(Primitive.LSR, - null, JOpcode.IUSHR, JOpcode.LUSHR, null, null); - addPrim(Primitive.ASR, - null, JOpcode.ISHR, JOpcode.LSHR, null, null); - addPrim(Primitive.POS, - null, null, null, null, null); - addPrim(Primitive.NEG, - null, JOpcode.INEG, JOpcode.LNEG, JOpcode.FNEG, JOpcode.DNEG); - } - - /** - * Generate code for the given arithmetic primitive, applied on - * the given arguments. - */ - protected void genArithPrim(Context ctx, - Primitive prim, - Tree[] args, - JType resType, - JType expectedType) - throws JCode.OffsetTooBigException { - int arity = args.length; - int resTypeIdx = getTypeIndex(resType); - - if ((prim == Primitive.LSL) - || (prim == Primitive.LSR) - || (prim == Primitive.ASR)) { - genLoad(ctx, args[0], resType); - genLoad(ctx, args[1], JType.INT); - } else { - for (int i = 0; i < arity; ++i) - genLoad(ctx, args[i], resType); - } - - if (prim == Primitive.NOT) { - if (resType == JType.LONG) { - ctx.code.emitPUSH(-1L); - ctx.code.emitLXOR(); - } else { - assert resType == JType.INT; - ctx.code.emitPUSH(-1); - ctx.code.emitIXOR(); - } - } else { - assert arithPrimMap.containsKey(prim); - JOpcode primInst = ((JOpcode[])arithPrimMap.get(prim))[resTypeIdx]; - if (primInst != null) - ctx.code.emit(primInst); - } - } - - /** Variable in which temporary objects are stored by the - * implementation of == */ - protected JLocalVariable eqEqTempVar; - - /** - * Generate code for the given equality primitive, applied on the - * given arguments. - */ - protected void genEqPrim(Context ctx, - Primitive prim, - Tree[] args, - JCode.Label target, - boolean when) - throws JCode.OffsetTooBigException { - JType maxType = getMaxType(args); - assert maxType.isReferenceType(): args[0]+" - "+args[1]+" : "+maxType; - // Generate code for all arguments - for (int i = 0; i < args.length; ++i) genLoad(ctx, args[i], maxType); - - if (prim == Primitive.ID) { - if (when) ctx.code.emitIF_ACMPEQ(target); - else ctx.code.emitIF_ACMPNE(target); - } else if (prim == Primitive.NI) { - if (!when) ctx.code.emitIF_ACMPEQ(target); - else ctx.code.emitIF_ACMPNE(target); - } else { - // Comparison between two references. We inline the code - // for the predefined (and final) "=="/"!=" operators, - // which check for null values and then forward the call - // to "equals". "==" could be defined as follows, if - // "null" was an object: - // final def ==(other: Any): boolean = - // if (this == null) other == null else this.equals(other) - assert prim == Primitive.EQ || prim == Primitive.NE; - - if (eqEqTempVar == null || eqEqTempVar.getOwner() != ctx.method) - eqEqTempVar = - ctx.method.addNewLocalVariable(JObjectType.JAVA_LANG_OBJECT, - "eqEqTemp$"); - - ctx.code.emitSTORE(eqEqTempVar); - ctx.code.emitDUP(); - JCode.Label ifNonNullLabel = ctx.code.newLabel(); - ctx.code.emitIFNONNULL(ifNonNullLabel); - ctx.code.emitPOP(); - ctx.code.emitLOAD(eqEqTempVar); - if (when ^ (prim != Primitive.EQ)) - ctx.code.emitIFNULL(target); - else - ctx.code.emitIFNONNULL(target); - JCode.Label afterLabel = ctx.code.newLabel(); - ctx.code.emitGOTO_maybe_W(afterLabel, ctx.useWideJumps); - ifNonNullLabel.anchorToNext(); - ctx.code.emitLOAD(eqEqTempVar); - JMethodType equalsType = - new JMethodType(JType.BOOLEAN, - new JType[] { JObjectType.JAVA_LANG_OBJECT }); - ctx.code.emitINVOKEVIRTUAL(JAVA_LANG_OBJECT, "equals", equalsType); - if (when ^ (prim != Primitive.EQ)) - ctx.code.emitIFNE(target); - else - ctx.code.emitIFEQ(target); - afterLabel.anchorToNext(); - } - } - - /** - * Generate code for the given comparison primitive, applied on - * the given arguments. - */ - protected void genCompPrim(Context ctx, - Primitive prim, - Tree[] args, - JCode.Label target, - boolean when) - throws JCode.OffsetTooBigException { - JType maxType = getMaxType(args); - assert !maxType.isReferenceType(): args[0]+" - "+args[1]+" : "+maxType; - int maxTypeIdx = getTypeIndex(maxType); - int intTypeIdx = getTypeIndex(JType.INT); - boolean intCompareWithZero = false; - // Generate code for all arguments, while detecting - // comparisons with 0, which can be optimised. - for (int i = 0; i < args.length; ++i) { - boolean isIntZero = false; - if (maxTypeIdx <= intTypeIdx) { - switch (args[i]) { - case Literal(AConstant constant): - int intVal; - switch (constant) { - case BOOLEAN(boolean value): - intVal = value ? 1 : 0; - break; - case BYTE(byte value): - intVal = value; - break; - case SHORT(short value): - intVal = value; - break; - case CHAR(char value): - intVal = value; - break; - case INT(int value): - intVal = value; - break; - default: - throw Debug.abort("unknown literal", constant); - } - if (intVal == 0) { - isIntZero = true; - if (i == 0) prim = prim.swap(); - } - } - } - if (intCompareWithZero || !isIntZero) - genLoad(ctx, args[i], maxType); - intCompareWithZero |= isIntZero; - } - - if (maxTypeIdx <= intTypeIdx && !intCompareWithZero) { - // Comparison between ints, no zeros involved - switch (maybeNegatedPrim(prim, !when)) { - case LT: ctx.code.emitIF_ICMPLT(target); break; - case LE: ctx.code.emitIF_ICMPLE(target); break; - case EQ: ctx.code.emitIF_ICMPEQ(target); break; - case NE: ctx.code.emitIF_ICMPNE(target); break; - case GE: ctx.code.emitIF_ICMPGE(target); break; - case GT: ctx.code.emitIF_ICMPGT(target); break; - default: throw Debug.abort("unknown primitive", prim); - } - } else { - // Comparison between longs, floats or double, or between - // one int and zero. - switch (maxType.getTag()) { - case JType.T_LONG: ctx.code.emitLCMP(); break; - case JType.T_FLOAT: ctx.code.emitFCMPG(); break; - case JType.T_DOUBLE: ctx.code.emitDCMPG(); break; - default: - ; // do nothing (int comparison with 0) - } - switch (maybeNegatedPrim(prim, !when)) { - case LT: ctx.code.emitIFLT(target); break; - case LE: ctx.code.emitIFLE(target); break; - case EQ: ctx.code.emitIFEQ(target); break; - case NE: ctx.code.emitIFNE(target); break; - case GE: ctx.code.emitIFGE(target); break; - case GT: ctx.code.emitIFGT(target); break; - default: throw Debug.abort("unknown primitive", prim); - } - } - } - - /** - * Generate code to throw the value returned by the argument. - */ - protected void genThrow(Context ctx, Tree arg) - throws JCode.OffsetTooBigException { - genLoad(ctx, arg, JAVA_LANG_OBJECT_T); - ctx.code.emitCHECKCAST(JAVA_LANG_THROWABLE_T); - ctx.code.emitATHROW(); - } - - /** - * Generate code to synchronise on the object and evaluate the - * code fragment. - */ - protected void genSynchronized(Context ctx, - Tree object, - Tree code, - JType expectedType) - throws JCode.OffsetTooBigException { - JLocalVariable monitorVar = - ctx.method.addNewLocalVariable(JAVA_LANG_OBJECT_T, "monitor"); - genLoad(ctx, object, JAVA_LANG_OBJECT_T); - ctx.code.emitSTORE(monitorVar); - ctx.code.emitLOAD(monitorVar); - ctx.code.emitMONITORENTER(); - int startPC = ctx.code.getPC(); - genLoad(ctx, code, expectedType); - int endPC = ctx.code.getPC(); - ctx.code.emitLOAD(monitorVar); - ctx.code.emitMONITOREXIT(); - - JCode.Label afterLabel = ctx.code.newLabel(); - ctx.code.emitGOTO(afterLabel); - int handlerPC = ctx.code.getPC(); - ctx.code.emitLOAD(monitorVar); - ctx.code.emitMONITOREXIT(); - ctx.code.emitATHROW(); - afterLabel.anchorToNext(); - - ctx.code.addFinallyHandler(startPC, endPC, handlerPC); - } - - /// Arrays - ////////////////////////////////////////////////////////////////////// - - /** - * Generate code to create an array of some basic type, whose size - * will be dynamically computed. - */ - protected void genArrayCreate(Context ctx, Primitive prim, Tree size) - throws JCode.OffsetTooBigException { - genLoad(ctx, size, JType.INT); - JType type; - switch (prim) { - case NEW_ZARRAY : type = JType.BOOLEAN; break; - case NEW_BARRAY : type = JType.BYTE; break; - case NEW_SARRAY : type = JType.SHORT; break; - case NEW_CARRAY : type = JType.CHAR; break; - case NEW_IARRAY : type = JType.INT; break; - case NEW_LARRAY : type = JType.LONG; break; - case NEW_FARRAY : type = JType.FLOAT; break; - case NEW_DARRAY : type = JType.DOUBLE; break; - default: throw Debug.abort("unexpected primitive", prim); - } - ctx.code.emitNEWARRAY(type); - } - - /** - * Generate code to create an array of references, whose size will - * be dynamically computed. - */ - protected void genRefArrayCreate(Context ctx, Tree size, Tree classNameLit) - throws JCode.OffsetTooBigException { - genLoad(ctx, size, JType.INT); - - String className; - switch (classNameLit) { - case Literal(STRING(String name)): className = name; break; - default: throw Debug.abort("invalid argument for oarray", classNameLit); - } - - JReferenceType elemType; - switch (className.charAt(0)) { - case '[': case 'L': - elemType = (JReferenceType)JType.parseSignature(className); break; - default: - elemType = new JObjectType(className); - } - ctx.code.emitANEWARRAY(elemType); - } - - /** - * Generate code to update an array. - */ - protected void genArrayUpdate(Context ctx, Tree array, Tree index, Tree value) - throws JCode.OffsetTooBigException { - genLoad(ctx, array, JAVA_LANG_OBJECT_T); - genLoad(ctx, index, JType.INT); - JType elemType = getArrayElementType(array); - if (elemType.isValueType()) - value = unbox(value); - genLoad(ctx, value, elemType); - ctx.code.emitASTORE(elemType); - } - - /** - * Generate code to load an element of an array. - */ - protected void genArrayAccess(Context ctx, Tree array, Tree index) - throws JCode.OffsetTooBigException { - genLoad(ctx, array, JAVA_LANG_OBJECT_T); - genLoad(ctx, index, JType.INT); - ctx.code.emitALOAD(getArrayElementType(array)); - } - - /** - * Generate code to load the length of an array. - */ - protected void genArrayLength(Context ctx, Tree array) - throws JCode.OffsetTooBigException { - genLoad(ctx, array, JAVA_LANG_OBJECT_T); - ctx.code.emitARRAYLENGTH(); - } - - /** - * Return the Java type of the elements of the array represented - * by the given tree. - */ - protected JType getArrayElementType(Tree array) { - JArrayType arrayType = (JArrayType)typeStoJ(array.type); - return arrayType.getElementType(); - } - - /// String concatenation - ////////////////////////////////////////////////////////////////////// - - protected Tree[] liftStringConcatenations(Tree tree) { - LinkedList accu = new LinkedList(); - liftStringConcatenations(tree, accu); - return (Tree[])accu.toArray(new Tree[accu.size()]); - } - - protected void liftStringConcatenations(Tree tree, LinkedList accu) { - switch (tree) { - case Apply(Select(Tree qualifier, Name selector), Tree[] args): { - Symbol funSym = ((Tree.Apply)tree).fun.symbol(); - if (prims.isPrimitive(funSym) - && prims.getPrimitive(funSym) == Primitive.CONCAT) { - liftStringConcatenations(qualifier, accu); - liftStringConcatenations(args[0], accu); - } else - accu.addLast(tree); - } break; - default: - accu.addLast(tree); - } - } - - /** - * Generate code to concatenate a list of expressions which return - * strings. - */ - protected void genStringConcatenation(Context ctx, Tree[] elements) - throws JCode.OffsetTooBigException { - // Create string buffer - ctx.code.emitNEW(JAVA_LANG_STRINGBUFFER); - ctx.code.emitDUP(); - ctx.code.emitINVOKESPECIAL(JAVA_LANG_STRINGBUFFER, - "<init>", - JMethodType.ARGLESS_VOID_FUNCTION); - - // Append all strings - for (int i = 0; i < elements.length; ++i) { - JType elemType = typeStoJ(elements[i].type); - if (!elemType.equals(JObjectType.JAVA_LANG_STRING) - && elemType.isReferenceType()) - elemType = JObjectType.JAVA_LANG_OBJECT; - genLoad(ctx, elements[i], elemType); - ctx.code.emitINVOKEVIRTUAL(JAVA_LANG_STRINGBUFFER, - "append", - new JMethodType(JAVA_LANG_STRINGBUFFER_T, - new JType[] { elemType })); - } - - // Get resulting string - ctx.code.emitINVOKEVIRTUAL(JAVA_LANG_STRINGBUFFER, - "toString", - new JMethodType(JObjectType.JAVA_LANG_STRING, - JType.EMPTY_ARRAY)); - } - - /// Primitives - ////////////////////////////////////////////////////////////////////// - - /** - * Return true iff the given symbol is a primitive, AND that - * primitive is recognized by this back-end, AND that primitive is - * a "jumping" one. - */ - protected boolean isJumpingPrimitive(Symbol sym) { - if (prims.isPrimitive(sym)) { - switch (prims.getPrimitive(sym)) { - case ID : case NI : case EQ : case NE : - case LT : case LE : case GE : case GT : - case ZNOT : case ZOR : case ZAND : - return true; - } - } - return false; - } - - /** - * Return true iff the given symbol is a primitive, AND that - * primitive is recognized by this back-end. - */ - protected boolean isKnownPrimitive(Symbol sym) { - if (isJumpingPrimitive(sym)) - return true; - - if (prims.isPrimitive(sym)) { - switch (prims.getPrimitive(sym)) { - case POS : case NEG : - case ADD : case SUB : case MUL : case DIV : case MOD : - case NOT : case OR : case XOR : case AND : - case LSL : case LSR : case ASR : - case NEW_ZARRAY : case NEW_BARRAY : case NEW_SARRAY : - case NEW_CARRAY : case NEW_IARRAY : case NEW_LARRAY : - case NEW_FARRAY : case NEW_DARRAY : case NEW_OARRAY : - case ZARRAY_GET : case BARRAY_GET : case SARRAY_GET : - case CARRAY_GET : case IARRAY_GET : case LARRAY_GET : - case FARRAY_GET : case DARRAY_GET : case OARRAY_GET : - case ZARRAY_SET : case BARRAY_SET : case SARRAY_SET : - case CARRAY_SET : case IARRAY_SET : case LARRAY_SET : - case FARRAY_SET : case DARRAY_SET : case OARRAY_SET : - case ZARRAY_LENGTH : case BARRAY_LENGTH : case SARRAY_LENGTH : - case CARRAY_LENGTH : case IARRAY_LENGTH : case LARRAY_LENGTH : - case FARRAY_LENGTH : case DARRAY_LENGTH : case OARRAY_LENGTH : - case IS : case AS : case ID : case NI : - case CONCAT : case THROW : case SYNCHRONIZED: - case B2B: case B2S: case B2C: case B2I: case B2L: case B2F: case B2D: - case S2B: case S2S: case S2C: case S2I: case S2L: case S2F: case S2D: - case C2B: case C2S: case C2C: case C2I: case C2L: case C2F: case C2D: - case I2B: case I2S: case I2C: case I2I: case I2L: case I2F: case I2D: - case L2B: case L2S: case L2C: case L2I: case L2L: case L2F: case L2D: - case F2B: case F2S: case F2C: case F2I: case F2L: case F2F: case F2D: - case D2B: case D2S: case D2C: case D2I: case D2L: case D2F: case D2D: - return true; - - case EQUALS : - case HASHCODE : - case TOSTRING : - case COERCE : - case BOX : - case UNBOX : - case APPLY : case UPDATE : case LENGTH : - return false; - default: - throw Debug.abort("unknown primitive", sym); - } - } else - return false; - } - - /** - * Negate the given primitive only if the second argument is - * true, otherwise return it as is. - */ - protected Primitive maybeNegatedPrim(Primitive prim, boolean negate) { - return negate ? prim.negate() : prim; - } - - /** - * Return all the arguments associated with the primitive - * represented by the given function call. - */ - protected Tree[] extractPrimitiveArgs(Tree.Apply call) { - Tree[] allArgs = Tree.cloneArray(1, call.args); - allArgs[0] = ((Tree.Select)(call.fun)).qualifier; - return allArgs; - } - - /** - * Return the unboxed version of the given tree. - */ - protected Tree unbox(Tree tree) { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (prims.getPrimitive(fun.symbol()) == Primitive.BOX) { - assert args.length == 1; - return args[0]; - } else - return tree; - default: - return tree; - } - } - - /// Modules - ////////////////////////////////////////////////////////////////////// - - /** - * Add field containing module instance, and code to initialize - * it, to current class. - */ - protected void addModuleInstanceField(Context ctx) { - ctx.clazz.addNewField(JAccessFlags.ACC_PUBLIC - | JAccessFlags.ACC_FINAL - | JAccessFlags.ACC_STATIC, - MODULE_INSTANCE_FIELD_NAME, - ctx.clazz.getType()); - - ctx.code.emitNEW(ctx.clazz.getName()); - ctx.code.emitINVOKESPECIAL(ctx.clazz.getName(), - CONSTRUCTOR_STRING, - JMethodType.ARGLESS_VOID_FUNCTION); - // The field is initialised by the constructor, so we don't - // need to do it here, creating the instance is sufficient. - } - - protected JMethod addNewScalaMethod(JClass clazz, - Symbol method, - int addFlags) { - JMethodType methodType = (JMethodType)typeStoJ(method.type()); - - Symbol[] params = method.valueParams(); - String[] argNames = new String[params.length]; - - for (int i = 0; i < argNames.length; ++i) - argNames[i] = params[i].name.toString(); - - return clazz.addNewMethod(javaModifiers(method) | addFlags, - method.name.toString(), - methodType.getReturnType(), - methodType.getArgumentTypes(), - argNames); - } - - /** - * Create a class which mirrors all public methods of the given - * module class as static methods, to enable the use of the module - * from Java. - */ - protected void dumpModuleMirrorClass(Context ctx, Symbol cSym, Pickle pickle) { - String mainName = javaName(cSym); - String mirrorName = mainName.substring(0, mainName.length() - 1); - - JClass mirrorClass = fjbgContext.JClass(JAccessFlags.ACC_SUPER - | JAccessFlags.ACC_PUBLIC - | JAccessFlags.ACC_FINAL, - mirrorName, - JAVA_LANG_OBJECT, - JClass.NO_INTERFACES, - ctx.sourceFileName); - Scope.SymbolIterator memberIt = - cSym.members().iterator(); - while (memberIt.hasNext()) { - Symbol member = memberIt.next(); - if (!member.isMethod() - || member.isInitializer() - || member.isStatic()) - continue; - - JMethod mirrorMeth = - addNewScalaMethod(mirrorClass, member, JAccessFlags.ACC_STATIC); - JExtendedCode mirrorCode = (JExtendedCode)mirrorMeth.getCode(); - - mirrorCode.emitGETSTATIC(mainName, - MODULE_INSTANCE_FIELD_NAME, - new JObjectType(mainName)); - JType[] argTypes = mirrorMeth.getArgumentTypes(); - for (int index = 0, i = 0; i < argTypes.length; ++i) { - mirrorCode.emitLOAD(index, argTypes[i]); - index += argTypes[i].getSize(); - } - mirrorCode.emitINVOKEVIRTUAL(mainName, - mirrorMeth.getName(), - (JMethodType)mirrorMeth.getType()); - mirrorCode.emitRETURN(mirrorMeth.getReturnType()); - - mirrorCode.setLineNumber(0, - mirrorCode.getPC(), - Position.line(member.pos)); - } - addScalaAttr(mirrorClass, pickle); - - writeClassFile(mirrorClass); - } - - /** - * Add the "Scala" attribute to the given class, in which the - * symbol table is saved. - */ - protected void addScalaAttr(JClass cls, Pickle pickle) { - // change this to true to enable .symbl file generation - if (false) { - pickles.add(cls); - pickles.add(pickle); - } else { - JOtherAttribute scalaAttr = - fjbgContext.JOtherAttribute(cls, - cls, - SCALA_ATTR, - pickle.bytes, - pickle.size()); - cls.addAttribute(scalaAttr); - } - } - - /// Names - ////////////////////////////////////////////////////////////////////// - - protected HashMap nameMap/*<Symbol,String>*/ = new HashMap(); - - /** - * Return a Java-compatible version of the name of the given - * symbol. The returned name is mangled and includes the names of - * the owners. - */ - protected String javaName(Symbol sym) { - Object value = nameMap.get(sym); - if (value != null) return (String)value; - String name = prims.getJREClassName(sym); - nameMap.put(sym, name); - return name; - } - - /// Types - ////////////////////////////////////////////////////////////////////// - - /** - * Return the Java modifiers for the given Scala symbol. - */ - protected int javaModifiers(Symbol sym) { - int flags = sym.flags; - int jFlags = 0; - - if (Modifiers.Helper.isPrivate(flags)) - jFlags |= JAccessFlags.ACC_PRIVATE; - else - jFlags |= JAccessFlags.ACC_PUBLIC; - - if (Modifiers.Helper.isAbstract(flags)) - jFlags |= JAccessFlags.ACC_ABSTRACT; - if (Modifiers.Helper.isInterface(flags)) - jFlags |= JAccessFlags.ACC_INTERFACE; - - if (Modifiers.Helper.isFinal(flags) - && !(Modifiers.Helper.isAbstract(flags) - || Modifiers.Helper.isInterface(flags))) - jFlags |= JAccessFlags.ACC_FINAL; - - if (sym.isStatic()) - jFlags |= JAccessFlags.ACC_STATIC; - - return jFlags; - } - - protected HashMap typeMap/*<Symbol,Type>*/ = new HashMap(); - protected void initTypeMap() { - typeMap.put(defs.ANY_CLASS, JObjectType.JAVA_LANG_OBJECT); - typeMap.put(defs.ANYREF_CLASS, JObjectType.JAVA_LANG_OBJECT); - } - - /** - * Return the Java type corresponding to the given Scala type. - */ - protected JType typeStoJ(Type tp) { - switch (tp) { - case ConstantType(Type base, _): - return typeStoJ(base); - case TypeRef(_, Symbol sym, _): - Object value = typeMap.get(sym); - if (value != null) return (JType)value; - JType jTp = new JObjectType(javaName(sym)); - typeMap.put(sym, jTp); - return jTp; - case UnboxedType(TypeTags.BYTE): - return JType.BYTE; - case UnboxedType(TypeTags.CHAR): - return JType.CHAR; - case UnboxedType(TypeTags.SHORT): - return JType.SHORT; - case UnboxedType(TypeTags.INT): - return JType.INT; - case UnboxedType(TypeTags.LONG): - return JType.LONG; - case UnboxedType(TypeTags.FLOAT): - return JType.FLOAT; - case UnboxedType(TypeTags.DOUBLE): - return JType.DOUBLE; - case UnboxedType(TypeTags.BOOLEAN): - return JType.BOOLEAN; - case UnboxedType(TypeTags.UNIT): - return JType.VOID; - case UnboxedType(TypeTags.STRING): - return JObjectType.JAVA_LANG_STRING; - case UnboxedArrayType(Type elementType): - return new JArrayType(typeStoJ(elementType)); - case MethodType(Symbol[] vparams, Type result): - JType[] argTypes = new JType[vparams.length]; - for (int i = 0; i < vparams.length; ++i) - argTypes[i] = typeStoJ(vparams[i].info()); - return new JMethodType(typeStoJ(result), argTypes); - default: - throw Debug.abort("invalid type", tp); - } - } - - /** - * Return the "index" of the given type. This index encodes the - * level in the hierarchy of basic types, with arrays and objects - * on top of everything. - */ - protected int getTypeIndex(JType tp) { - return getTypeIndex(tp.getTag()); - } - - /** - * Return the "index" of the given type. - */ - protected int getTypeIndex(int tp) { - switch (tp) { - case JType.T_BOOLEAN: return 0; - case JType.T_BYTE: - case JType.T_CHAR: - case JType.T_SHORT: - case JType.T_INT: return 1; - case JType.T_LONG: return 2; - case JType.T_FLOAT: return 3; - case JType.T_DOUBLE: return 4; - case JType.T_ARRAY: - case JType.T_OBJECT: return 5; - default: return -1; - } - } - - /** - * Return the maximum of the types of all the given trees. All - * reference types are considered to be equivalent, and if several - * reference types are present in the trees, any one of them is - * returned. - */ - protected JType getMaxType(Tree[] trees) { - JType maxType = JType.BOOLEAN; - int maxTypeIdx = getTypeIndex(maxType); - - for (int i = 0; i < trees.length; ++i) { - JType argType = typeStoJ(trees[i].type); - if (getTypeIndex(argType) > maxTypeIdx) { - maxType = argType; - maxTypeIdx = getTypeIndex(maxType); - } - } - return maxType; - } - protected JType getMaxType(Tree tree1, Tree tree2) { - JType type1 = typeStoJ(tree1.type); - JType type2 = typeStoJ(tree2.type); - return getTypeIndex(type1) > getTypeIndex(type2) ? type1 : type2; - } - - /// Line numbers - ////////////////////////////////////////////////////////////////////// - - int[] pcStack = new int[32]; - int pcStackDepth = 0; - void startCodeForTree(Context ctx, Tree tree) { - if (pcStackDepth == pcStack.length) { - int[] newPCStack = new int[pcStack.length * 2]; - System.arraycopy(pcStack, 0, newPCStack, 0, pcStack.length); - pcStack = newPCStack; - } - pcStack[pcStackDepth++] = (ctx.code == null ? 0 : ctx.code.getPC()); - } - - void endCodeForTree(Context ctx, Tree tree) { - assert pcStackDepth > 0; - int startPC = pcStack[--pcStackDepth]; - if (ctx.code != null) - ctx.code.completeLineNumber(startPC, - ctx.code.getPC(), - Position.line(tree.pos)); - } - - protected void genLocalVariableTable(Context ctx) { - JLocalVariable[] vars = ctx.method.getLocalVariables(); - - if (!global.debuginfo || vars.length == 0) - return; - - JConstantPool pool = ctx.clazz.getConstantPool(); - int pc = ctx.code.getPC(); - int anonCounter = 1; - - ByteBuffer lvTab = ByteBuffer.allocate(2 + 10 * vars.length); - lvTab.putShort((short)vars.length); - for (int i = 0; i < vars.length; i++) { - JLocalVariable lv = vars[i]; - String name = (lv.getName() == null) - ? "<anon" + (anonCounter++) + ">" : lv.getName(); - lvTab.putShort((short)0); - lvTab.putShort((short)pc); - lvTab.putShort((short)pool.addUtf8(name)); - lvTab.putShort((short)pool.addUtf8(lv.getType().getSignature())); - lvTab.putShort((short)lv.getIndex()); - } - JAttribute attr = - fjbgContext.JOtherAttribute(ctx.clazz, - ctx.method, - "LocalVariableTable", - lvTab.array()); - ctx.code.addAttribute(attr); - } - - - /// Context - ////////////////////////////////////////////////////////////////////// - - /** - * Record the entry into a class, and return the appropriate - * context. - */ - protected Context enterClass(Context ctx, Symbol cSym) { - String javaName = javaName(cSym); - - boolean serializable = - global.getAttrArguments(cSym, defs.SCALA_SERIALIZABLE_CONSTR) != null; - - boolean cloneable = - global.getAttrArguments(cSym, defs.SCALA_CLONEABLE_CONSTR) != null; - - scalac.symtab.Type[] baseTps = cSym.info().parents(); - assert baseTps.length > 0 : Debug.show(cSym); - - int offset; - String superClassName; - if (cSym.isInterface()) { - offset = baseTps[0].symbol() == defs.ANY_CLASS ? 1 : 0; - superClassName = JAVA_LANG_OBJECT; - } else { - offset = 1; - superClassName = javaName(baseTps[0].symbol()); - } - String[] interfaceNames = new String[baseTps.length - offset - + (serializable ? 1 : 0) - + (cloneable ? 1 : 0)]; - for (int i = offset; i < baseTps.length; ++i) { - Symbol baseSym = baseTps[i].symbol(); - assert baseSym.isInterface() : cSym + " implements " + baseSym; - interfaceNames[i - offset] = javaName(baseSym); - } - if (serializable) - interfaceNames[interfaceNames.length - 1 - (cloneable ? 1 : 0)] = - "java.io.Serializable"; - if (cloneable) - interfaceNames[interfaceNames.length - 1] = "java.lang.Cloneable"; - - JClass cls = fjbgContext.JClass(javaModifiers(cSym) - & ~JAccessFlags.ACC_STATIC - | JAccessFlags.ACC_SUPER, - javaName, - superClassName, - interfaceNames, - ctx.sourceFileName); - - return ctx.withClass(cls, - cSym.isModuleClass() && ctx.clazz == null, - cSym.isSubClass(JAVA_RMI_REMOTE_CLASS)); - } - - protected void leaveClass(Context ctx, Symbol cSym) { - JClass clazz = ctx.clazz; - - Pickle pickle = (Pickle)global.symdata.get(cSym); - if (pickle != null) - if (ctx.isModuleClass) - dumpModuleMirrorClass(ctx, cSym, pickle); - else - addScalaAttr(clazz, pickle); - - writeClassFile(clazz); - } - - /** - * Record the entry into a method, and return the appropriate - * context. - */ - protected Context enterMethod(Context ctx, - Tree.DefDef mDef, - boolean useWideJumps) { - Symbol mSym = mDef.symbol(); - - global.log("entering method " + Debug.show(mSym) - + " (type: " + Debug.show(mSym.info()) + ")" - + " wide jumps? " + useWideJumps); - - JMethod method = addNewScalaMethod(ctx.clazz, mSym, 0); - - Map locals = new HashMap(); - Symbol[] args = mSym.valueParams(); - JType[] argTypes = method.getArgumentTypes(); - - int firstPos = mSym.isStatic() ? 0 : 1; - for (int i = 0, pos = firstPos; i < argTypes.length; ++i) { - locals.put(args[i], new Integer(pos)); - pos += argTypes[i].getSize(); - } - - if ((mSym.flags & Modifiers.BRIDGE) != 0) - method.addAttribute(fjbgContext.JOtherAttribute(ctx.clazz, - method, - "Bridge", - new byte[]{})); - - if (ctx.isRemote && mSym.isPublic()) { - // (see http://java.sun.com/docs/books/vmspec/html/ClassFile.doc.html#3129) - // Exceptions_attribute { - // .. - // u2 number_of_exceptions; - // u2 exception_index_table[number_of_exceptions]; - // } - JConstantPool cp = ctx.clazz.getConstantPool(); - int reInx = cp.addClass(JAVA_RMI_REMOTEEXCEPTION); - ByteBuffer contents = ByteBuffer.allocate(4); // u2 + u2[1] - contents.putShort((short)1); - contents.putShort((short)reInx); - global.log("adding 'Exceptions_attribute' " + contents.toString() - + " for remote method " + mSym.name.toString()); - method.addAttribute(fjbgContext.JOtherAttribute(ctx.clazz, - method, - "Exceptions", - contents.array())); - } - - return ctx.withMethod(method, locals, useWideJumps); - } - - protected void leaveMethod(Context ctx) { - genLocalVariableTable(ctx); - global.log("leaving method"); - } - - /// I/O - ////////////////////////////////////////////////////////////////////// - - /** Writes the given class to a file. */ - protected void writeClassFile(JClass clazz) { - File file = getFile(clazz, ".class"); - try { - clazz.writeTo(file); - global.operation("wrote " + file); - } catch (IOException exception) { - if (global.debug) exception.printStackTrace(); - global.error("could not write file " + file); - } - } - - /** Writes the given pickle for given class to a file. */ - protected void writeSymblFile(JClass clazz, Pickle pickle) { - File file = getFile(clazz, ".symbl"); - try { - pickle.writeTo(file); - global.operation("wrote " + file); - } catch (IOException exception) { - if (global.debug) exception.printStackTrace(); - global.error("could not write file " + file); - } - } - - /** Returns the file with the given suffix for the given class. */ - protected File getFile(JClass clazz, String suffix) { - String path = clazz.getName().replace('.', File.separatorChar); - return new File(global.outpath + File.separatorChar + path + suffix); - } - - /// Misc. - ////////////////////////////////////////////////////////////////////// - - /** - * Add value members (i.e. fields) to current class. - */ - protected void addValueClassMembers(Context ctx, Tree.ClassDef cDef) { - Symbol cSym = cDef.symbol(); - Scope.SymbolIterator memberIt = - cSym.members().iterator(); - while (memberIt.hasNext()) { - Symbol member = memberIt.next(); - if (member.isTerm() && !member.isMethod()) { - int flags = javaModifiers(member); - if (global.getAttrArguments(member,defs.SCALA_TRANSIENT_CONSTR) - != null) - flags |= JAccessFlags.ACC_TRANSIENT; - if (global.getAttrArguments(member,defs.SCALA_VOLATILE_CONSTR) - != null) - flags |= JAccessFlags.ACC_VOLATILE; - ctx.clazz.addNewField(flags, - member.name.toString(), - typeStoJ(member.info())); - } - } - } - - protected void completeClassConstructor(Context ctx, Symbol cSym) { - if (ctx.isModuleClass) - addModuleInstanceField(ctx); - AConstant[] aargs = - global.getAttrArguments(cSym, SCALA_SERIAL_VERSION_UID_CONSTR); - if (aargs == null) - return; - assert aargs.length == 1 : "Wrong attribute arguments: "; - String fieldName = "serialVersionUID"; - JField field = ctx.clazz.addNewField - (JAccessFlags.ACC_STATIC | JAccessFlags.ACC_PUBLIC, fieldName, - JType.LONG); - genLoadLiteral(ctx, aargs[0], JType.LONG); - ctx.code.emitPUTSTATIC(ctx.clazz.getName(), fieldName, JType.LONG); - } - - /** - * Return the class constructor method of the given class. - */ - private JMethod getClassConstructorMethod(Context ctx) { - JMethod[] methods = ctx.clazz.getMethods(); - JMethod clinit = null; - for (int i = 0; i < methods.length; ++i) { - if (methods[i].getName().equals("<clinit>")) { - clinit = methods[i]; - break; - } - } - return clinit != null - ? clinit - : ctx.clazz.addNewMethod(JAccessFlags.ACC_PUBLIC - | JAccessFlags.ACC_STATIC, - "<clinit>", - JType.VOID, - JType.EMPTY_ARRAY, - Strings.EMPTY_ARRAY); - } - - - /** - * Return true iff the given symbol is a static (in the Java - * sense) member of its owner. - */ - protected boolean isStaticMember(Symbol sym) { - return sym.isStatic(); - } -} - -/** - * A compilation context, which records information about the class - * and the method currently being generated. - */ -class Context { - public final String sourceFileName; - public final JClass clazz; - public final JMethod method; - public final JExtendedCode code; - public final Map/*<Symbol,JLocalVariable>*/ locals; - public final Map/*<Symbol,Pair<JCode.Label,Tree[]>>*/ labels; - public final boolean useWideJumps; - public final boolean isModuleClass; - public final boolean isRemote; - - public final static Context EMPTY = - new Context(null, null, null, null, null, false, false, false); - - private Context(String sourceFileName, - JClass clazz, - JMethod method, - Map locals, - Map labels, - boolean useWideJumps, - boolean isModuleClass, - boolean isRemote) { - this.sourceFileName = sourceFileName; - this.clazz = clazz; - this.method = method; - if (method == null || method.isAbstract()) - this.code = null; - else - this.code = (JExtendedCode)method.getCode(); - this.locals = locals; - this.labels = labels; - this.useWideJumps = useWideJumps; - this.isModuleClass = isModuleClass; - this.isRemote = isRemote; - } - - public Context withSourceFileName(String sourceFileName) { - return new Context(sourceFileName, - null, - null, - null, - null, - false, - false, - false); - } - - public Context withClass(JClass clazz, boolean isModuleClass, boolean isRemote) { - return new Context(this.sourceFileName, - clazz, - null, - null, - null, - false, - isModuleClass, - isRemote); - } - - public Context withMethod(JMethod method, Map locals, boolean useWideJumps) { - assert this.clazz == method.getOwner(); - return new Context(this.sourceFileName, - this.clazz, - method, - locals, - new HashMap(), - useWideJumps, - this.isModuleClass, - this.isRemote); - } -} diff --git a/sources/scalac/backend/msil/GenMSIL.java b/sources/scalac/backend/msil/GenMSIL.java deleted file mode 100644 index 3850369356..0000000000 --- a/sources/scalac/backend/msil/GenMSIL.java +++ /dev/null @@ -1,2632 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.backend.msil; - -import scalac.Global; -import scalac.CompilationUnit; - -import scalac.util.Debug; - -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; -import scalac.util.SourceRepresentation; -import scalac.ast.Tree; -import scalac.ast.TreeList; -import scalac.atree.AConstant; -import Tree.*; -import scalac.symtab.Symbol; -import scalac.symtab.TypeTags; -import scalac.symtab.Modifiers; -import scalac.symtab.Definitions; -import scalac.symtab.classfile.Pickle; -import scalac.symtab.classfile.CLRTypes; - -import scalac.backend.Primitive; -import scalac.backend.Primitives; - -import scala.tools.util.Position; - -import ch.epfl.lamp.compiler.msil.*; -import ch.epfl.lamp.compiler.msil.emit.*; - -import Item.*; - -import java.util.List; -import java.util.Map; -import java.util.HashMap; -import java.util.Iterator; - -/** - * Generates MS IL code via Reflection.Emit-like API - * (ch.epfl.lamp.compiler.msil.emit package) - * - * @author Nikolay Mihaylov - */ -public final class GenMSIL { - - //################################################################ - - // The position of the paramater in the parameter list - private final Map/*<Symbol, Integer>*/ params = new HashMap(); - - // The LocalBuilder corresponding to the local variable symbol - private final Map/*<Symbol, LocalBuilder>*/ locals = new HashMap(); - - // mapping from LabelDef symbols to labels - private final Map/*<Symbol, Label>*/ sym2label = new HashMap(); - - // the code generator for the current method - private ILGenerator code; - - private final Global global; - private final TypeCreator tc; - private final Definitions defs; - private final Primitives primitives; - private final ItemFactory items; - - private static final Item TRUE_ITEM = Item.CondItem(Test.True, null, null); - private static final Item FALSE_ITEM = Item.CondItem(Test.False, null, null); - - /** The public entry point into the code generator. */ - public static void translate(Global global, CompilationUnit[] units) { - TypeCreator tc = new TypeCreator(global); - GenMSIL translator = new GenMSIL(global, tc); - tc.init(); - tc.collectSymbols(units); - tc.initAssembly(); - for (int i = 0; i < units.length; i++) translator.apply(units[i]); - tc.saveAssembly(); - } - - /** - * The private constructor of the code generator. - */ - private GenMSIL(Global global, TypeCreator tc) { - this.global = global; - this.defs = global.definitions; - this.primitives = global.primitives; - this.tc = tc; //new TypeCreator(global, this, phase); - this.items = new ItemFactory(this); - } - - - private String getSourceFilename() { - assert currUnit != null; - return SourceRepresentation.escape(currUnit.source.getFile().getPath()); - } - - // keeps track of the current compilation unit for better error reporting - private CompilationUnit currUnit; - - /** - * The main entry point into the code generator. Called from translate - * for every compilation unit. - */ - private void apply(CompilationUnit unit) { - currUnit = unit; - for (int i = 0; i < unit.body.length; i++) { - Tree tree = unit.body[i]; - Symbol sym = tree.symbol(); - try { - switch (tree) { - case Empty: break; - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - genClass(sym, body); - break; - case PackageDef(_, Template(_ , Tree[] body)): - genPackage(body); - break; - default: - throw Debug.abort - ("Illegal top-level definition: " + Debug.show(tree)); - } - } catch (Throwable e) { - currUnit.error(tree.pos, "Exception caught: " + e.getMessage()); - e.printStackTrace(); - tc.saveAssembly(); - System.exit(1); - } - } - } - - /** - * Generate the code for a Package definition. - */ - private void genPackage(Tree[] body) { - for (int i = 0; i < body.length; i++) { - Symbol sym = body[i].symbol(); - switch (body[i]) { - case Empty: - break; - - case ClassDef(_, _, _, _, _, Template(_, Tree[] classBody)): - Type type = tc.getType(sym); - assert type instanceof TypeBuilder - : Debug.show(sym) + " => [" + type.Assembly() + "]" + type; - if (type instanceof TypeBuilder) - genClass(sym, classBody); - break; - - case PackageDef(_, Template(_ , Tree[] body2)): - genPackage(body2); - break; - - default: - throw Debug.abort("Class definition expected", Debug.show(sym)); - } - } - } - - /** The symbol of the class that is currently being compiled. */ - private Symbol currentClass; - - /** The method that is currently being compiled. */ - private MethodBase currentMethod; - - - private static final byte[] NO_SYMTAB = new byte[] {1, 0, 0, 0}; - /* - * Emit the symbol table for the class given class as an MSIL attribute. - */ - private void emitSymtab(Symbol clazz) { - ConstructorInfo symtabConstr = tc.SYMTAB_DEFAULT_CONSTR; - byte[] symtab = null; - Pickle pickle = (Pickle)global.symdata.get(clazz); - if (pickle == null) { - symtab = NO_SYMTAB; - } else { - symtabConstr = tc.SYMTAB_CONSTR; - symtab = new byte[pickle.size() + 8]; - symtab[0] = 1; - for (int size = pickle.size(), i = 2; i < 6; i++) { - symtab[i] = (byte)(size & 0xff); - size >>= 8; - } - System.arraycopy(pickle.bytes, 0, symtab, 6, pickle.size()); - } - TypeBuilder type = (TypeBuilder) tc.getType(clazz); - if (clazz.isModuleClass()) { - TypeBuilder t = tc.getStaticType(clazz); - if (t != null) { - type.SetCustomAttribute(tc.SYMTAB_DEFAULT_CONSTR, NO_SYMTAB); - type = t; - if (global.args.debuginfo.value) - type.setPosition(Position.line(clazz.pos), getSourceFilename()); - } - } - type.SetCustomAttribute(symtabConstr, symtab); - } - - /* - * Generate the code for a class definition - */ - private void genClass(Symbol clazz, Tree[] body) { - Symbol outerClass = currentClass; - currentClass = clazz; - if (clazz.isModuleClass()) { - tc.getModuleField(clazz); - } - final TypeBuilder type = (TypeBuilder)tc.getType(clazz); - if (global.args.debuginfo.value) - type.setPosition(Position.line(clazz.pos), getSourceFilename()); - emitSymtab(clazz); - for (int i = 0; i < body.length; i++) { - Symbol sym = body[i].symbol(); - switch (body[i]) { - case Empty: - break; - - case ValDef(_, _, _, _): - // just to generate the field declaration - // the rhs should've been moved to the constructor body - tc.createField(sym); - break; - - case ClassDef(_, _, _, _, _, Template impl): - genClass(sym, impl.body); - break; - - case DefDef(_, _, _, ValDef[][] vparams, Tree tpe, Tree rhs): - if (!sym.isDeferred()) { - currentMethod = tc.getMethod(sym); - if (tc.isEntryPoint(sym) && tc.moreThanOneEntryPoint()) - currUnit.warning(body[i].pos, - "Program has more than one" - + " entry point defined"); - genDef(sym, vparams[0], rhs, msilType(tpe.type)); - } - break; - - default: - assert false : "Illegal class body definition: " - + Debug.show(body[i]); - } - } - if (tc.isCloneable(clazz)) { - Symbol cloneSym = clazz.lookup(Names.clone); - if (cloneSym.isNone()) { - short mods = MethodAttributes.Public - | MethodAttributes.Virtual - | MethodAttributes.HideBySig; - ILGenerator code = - type.DefineMethod("Clone", mods, tc.OBJECT, Type.EmptyTypes) - .GetILGenerator(); - code.Emit(OpCodes.Ldarg_0); - code.Emit(OpCodes.Call, tc.MEMBERWISE_CLONE); - code.Emit(OpCodes.Ret); - } - } - currentClass = outerClass; - } //genClass() - - - /* - * Specifies if the currently processed tree node is the last expression - * in a function so the generated code can be optimized: emitting ret - * instead of branch, emitting tailcalls, etc. - */ - private boolean lastExpr; - - private boolean enableTailCalls = false; - - private Label methodEnd = null; - - // set by backward jumps to show that the code ofter them is unreachable - private boolean unreachable = false; - - // used to push down the exit label of conditional expressions - private Label exitLabel; - - /* - * Generate code for constructors and methods. - */ - private void genDef(Symbol sym, ValDef[] parameters, Tree rhs, MSILType toType) { - MethodBase method = tc.getMethod(sym); - - params.clear(); - locals.clear(); - int argOffset = method.IsStatic() ? 0 : 1; - for (int i = 0; i < parameters.length; i++) { - params.put(parameters[i].symbol(), new Integer(i + argOffset)); - } - if (method.IsConstructor()) { - ConstructorInfo ctor = (ConstructorInfo) method; - code = ((ConstructorBuilder)ctor).GetILGenerator(); - methodEnd = code.DefineLabel(); - if (global.args.debuginfo.value) - code.setPosition(Position.line(rhs.pos)); - if (sym.owner().isModuleClass() - && sym.owner().owner().isPackageClass()) { - Tree[] cstats = null; - switch (rhs) { - case Block(Tree[] stats, Tree value): - TreeList stms = new TreeList(); - for (int i = 0; i < stats.length; i++) { - switch (stats[i]) { - case Block(Tree[] stats2, Tree value2): - stms.append(stats2); - stms.append(value2); - break; - default: - stms.append(stats[i]); - } - } - switch (value) { - case Block(Tree[] stats2, Tree value2): - stms.append(stats2); - stms.append(value2); - break; - } - cstats = stms.toArray(); - break; - default: - cstats = new Tree[]{rhs}; - } - - // emit the call to the superconstructor - drop(gen(cstats[0], MSILType.VOID)); - closeMethod(methodEnd); - ConstructorBuilder cctor = ((TypeBuilder)(method.DeclaringType)). - DefineConstructor((short)(MethodAttributes.Static - | MethodAttributes.Public), - CallingConventions.Standard, - Type.EmptyTypes); - currentMethod = cctor; - code = cctor.GetILGenerator(); - if (global.args.debuginfo.value) - code.setPosition(Position.line(sym.owner().pos)); - // initialize the static module reference - code.Emit(OpCodes.Newobj, ctor); - code.Emit(OpCodes.Stsfld, tc.getModuleField(currentClass)); - for (int i = 1; i < cstats.length; i++) { - drop(gen(cstats[i], MSILType.VOID)); - } - code.Emit(OpCodes.Ret); // conclude the static constructor - } else { - drop(gen(rhs, MSILType.VOID)); - closeMethod(methodEnd); - } - } else if (!method.IsAbstract()) { - lastExpr = true; - code = ((MethodBuilder)method).GetILGenerator(); - methodEnd = code.DefineLabel(); - if (global.args.debuginfo.value) - code.setPosition(Position.line(rhs.pos)); - Item item = gen(rhs, toType); - if (returnsVoid(method)) - drop(item); - else - coerce(load(item), toType); // FIXME: coerce??? - closeMethod(methodEnd); - if (currentClass.isModuleClass()) { - MethodBuilder staticMethod = tc.getStaticObjectMethod(sym); - if (staticMethod != null) { - code = staticMethod.GetILGenerator(); - if (global.args.debuginfo.value) - code.setPosition(Position.line(sym.pos)); - code.Emit(OpCodes.Ldsfld, tc.getModuleField(currentClass)); - for (int i = 0; i < parameters.length; i++) - emitLdarg(i); - code.Emit(OpCodes.Call, (MethodInfo)method); - code.Emit(OpCodes.Ret); - } - } - } - - lastExpr = false; - code = null; - methodEnd = null; - } // genDef(); - - private void closeMethod(Label methodEnd) { - code.MarkLabel(methodEnd); - code.Emit(OpCodes.Ret); - } - - /* - * Check if the result type of a method is void - */ - private boolean returnsVoid(MethodBase method) { - return method.IsConstructor() || - (((MethodInfo)method).ReturnType == tc.VOID); - } - - private boolean returnsVoid(Symbol fun) { - switch (fun.type()) { - case MethodType(_, scalac.symtab.Type restype): - return restype.isSameAs(defs.UNIT_TYPE().unbox()); - default: - return false; - } - } - - /* - * Emit the code for this. - */ - private void emitThis() { - if (currentMethod.IsStatic()) { - if (currentMethod.IsConstructor()) { - code.Emit(OpCodes.Ldsfld, tc.getModuleField(currentClass)); - } else - throw Debug.abort ("Static methods don't have 'this' pointer"); - } else - code.Emit(OpCodes.Ldarg_0); - } - - - /* - * Sanity checks for items. - */ - private Item check(Item item) { - assert item != null && item.type != null : "" + item; - return item; - } - - /* - * - */ - private Item genLoad(Tree tree, MSILType toType) { - return load(gen(tree, toType)); - } - - /** the position of the treenode which is currently being processed. */ - private int pos; - - /* - * The main generator function. It keeps track of - * the current position in the tree for better error messages - */ - private Item gen(Tree tree, MSILType toType) { - unreachable = false; - if (global.args.debuginfo.value - && code != null && tree.pos != Position.NOPOS - && Position.line(tree.pos) != Position.line(pos)) - { - code.setPosition(Position.line(tree.pos)); - } - int tmpPos = pos; - pos = tree.pos; - Item item = null; - //i = gen0(tree, toType); - try { - item = gen0(tree, toType); - assert item.type.equals(toType) - || item.type.equals(unboxValueType(toType)) - : "" + item + " <> " + toType + "; tree = " + tree.getClass(); - } - catch (Throwable e) { - currUnit.error(tree.pos, "Exception caught: " + e.getMessage()); - e.printStackTrace(); - tc.saveAssembly(); - System.exit(1); -// + (global.debug ? "" : "; Use -debug to get a stack trace.")); -// //if (global.debug) -// e.printStackTrace(); -// //System.exit(1); - //throw Debug.abort(tree, e); - throw Debug.abort(e); - } - pos = tmpPos; - return check(item); - } - - /* - * Generate the code corresponding to the given tree node - */ - private Item gen0(Tree tree, MSILType toType) { - Symbol sym = tree.hasSymbol() ? tree.symbol() : null; - Item item = null; - switch (tree) { - case Empty: - return items.VoidItem(); - - case Block(Tree[] stats, Tree value): - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - for (int i = 0; i < stats.length; i++) { - drop(gen(stats[i], MSILType.VOID)); - } - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - return gen(value, toType); - - case ValDef(_, Name name, Tree tpe, Tree rhs): - LocalBuilder local = code.DeclareLocal(tc.getType(sym)); - local.SetLocalSymInfo(tree.symbol().name.toString()); - locals.put(sym, local); - if (rhs == Tree.Empty) - return items.VoidItem(); - MSILType type = msilType(tpe.type); - genLoad(rhs, type); - return check(store(items.LocalItem(local))); - - case Ident(_): - if (sym.isModule()) { - FieldInfo field = tc.getModuleField(sym); - // force the loading of the module - item = coerce(load(items.StaticItem(field)), toType); - } else { - MSILType type = msilType(sym.info()); - Integer slot = (Integer) params.get(sym); - if (slot != null) { - item = items.ArgItem(type, slot.intValue()); - } else { - LocalBuilder local = (LocalBuilder) locals.get(sym); - if (local != null) - item = items.LocalItem(local); - else { - assert sym.isStatic() : Debug.show(sym); - FieldInfo field = tc.getField(sym); - assert field != null : Debug.show(sym); - if (field.IsLiteral()) { - assert field.FieldType.IsEnum() - && field.getValue() != null - : field.toString(); - return coerce(mkLiteral(msilType(field.FieldType), - field.getValue()), - toType); - } - return coerce(items.StaticItem(field), toType); - } - } - } - return coerce(item, toType); - - case Select(Tree qualifier, _): - if (sym.isModule()) { - assert !sym.isJava() : "Cannot treat Java class '" + - Debug.show(sym) + "' as value."; - return coerce(load(items.StaticItem(tc.getModuleField(sym))), toType); - } - assert !sym.isStatic() :Debug.show(sym); - item = items.SelectItem(genLoad(qualifier, msilType(qualifier)), - tc.getField(sym)); - return coerce(item, toType); - - case Apply(Tree fun, Tree[] args): - Item i = check(genApply(fun, args, msilType(tree.type))); - return coerce(i, toType); - - case Assign(Tree lhs, Tree rhs): - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - MSILType type = msilType(lhs.type); - Item var = gen(lhs, type); - genLoad(rhs, type); - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - return check(store(var)); - - case New(Tree init): - switch (init) { - case Apply(Tree fun, Tree[] args): - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - ConstructorInfo ctor = (ConstructorInfo) tc.getMethod(fun.symbol()); - loadArgs(args, ctor.GetParameters()); - code.Emit(OpCodes.Newobj, ctor); - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - return coerce(items.StackItem(msilType(ctor.DeclaringType)), - toType); - default: - throw Debug.abort("Incorrect tree", init); - } - - case This(_): - return coerce(items.SelfItem(tc.getType(sym)), toType); - - case Super(_, _): - return coerce(items.SelfItem(tc.getType(sym)), toType); - - case Literal(AConstant value): - if (toType == MSILType.VOID) - return items.VoidItem(); - return coerce(items.LiteralItem(value), toType); - - case Return(Tree expr): - genLoad(expr, msilType(expr)); - code.Emit(OpCodes.Ret); - //code.Emit(OpCodes.Br, methodEnd); - return items.VoidItem(); - - case If(Tree cond, Tree thenp, Tree elsep): - item = genIf(cond, thenp, elsep, toType); - return check(item); - - case LabelDef(_, Ident[] params, Tree rhs): - Label l = code.DefineLabel(); - code.MarkLabel(l); - sym2label.put(sym, new LabelDescr(l, params)); - return gen(rhs, toType); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - boolean tmpLastExpr = lastExpr; lastExpr = false; - Item loc = gen(test, MSILType.I4); - switch (loc) { - case ArgItem(_): - case LocalItem(_): - case LiteralItem(_): - break; - default: - loc = items.LocalItem(code.DeclareLocal(tc.INT)); - store(loc); - } - lastExpr = tmpLastExpr; - Label tmpExitLabel = exitLabel; - if (exitLabel == null) - exitLabel = code.DefineLabel(); - - Label nextCase = code.DefineLabel(); - assert tags.length == bodies.length; - for (int i = 0; i < tags.length; i++) { - load(loc); - loadI4(tags[i]); - code.Emit(OpCodes.Bne_Un, nextCase); - genLoad(bodies[i], toType); -// if (lastExpr) -// code.Emit(OpCodes.Ret); -// else - if (!unreachable) - code.Emit(OpCodes.Br, exitLabel); - code.MarkLabel(nextCase); - nextCase = code.DefineLabel(); - } - Item i = genLoad(otherwise, toType); - if (tmpExitLabel == null) - resolve(exitLabel); - exitLabel = tmpExitLabel; - return i; - - default: - throw Debug.abort("Dunno what to do", tree); - } - } //gen() - - /* Generate code for conditional expressions. - */ - private Item genIf(Tree condp, Tree thenp, Tree elsep, MSILType toType) { - Item iThen = null; - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - Item.CondItem cond = mkCond(gen(condp, msilType(condp.type))); - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - - if (elsep == Tree.Empty && toType == MSILType.VOID) { - if (cond.success == null) { - Chain success = new Chain(code.DefineLabel(), null); - branch(cond.test, success); - iThen = genLoad(thenp, toType); - resolve(success); - resolve(cond.failure); - } else { - Chain fail = (cond.failure != null) ? - cond.failure : new Chain(code.DefineLabel(), null); - branch(cond.test, fail); - resolve(cond.success); - iThen = genLoad(thenp, toType); - resolve(fail); - } - } else { - Chain fail = cond.failure != null ? - cond.failure : new Chain(code.DefineLabel(), null); - branch(cond.test, fail); - resolve(cond.success); - if (exitLabel == null) - exitLabel = code.DefineLabel(); - Item thenItem = gen(thenp, toType); - iThen = load(coerce(thenItem, toType)); -// if (lastExpr) -// code.Emit(OpCodes.Ret); -// else - if (!unreachable) - code.Emit(OpCodes.Br, exitLabel); - resolve(fail); - Item iElse = genLoad(elsep, toType); - if (tmpExitLabel == null) - resolve(exitLabel); - exitLabel = tmpExitLabel; - } - return iThen; - } //genIf - - /* Coerce the item to the specified type. */ - private Item coerce(Item item, MSILType toType) { - assert item != null && toType != null : "" + item + " => " + toType; - if (item.type.equals(toType)) - return item; - if (toType == MSILType.VOID) - return drop(item); - switch (item) { - case VoidItem(): - assert toType == MSILType.VOID : "" + toType; - return item; - case SelfItem(): - assert item.type.isSubtypeOf(toType); - item.type = toType; - return item; - case StackItem(): - MSILType utype = unboxValueType(toType); - if (item.type.isValueType() && utype != null) - toType = utype; - emitConvert(item.type, toType); - item.type = toType; - return item; - case LiteralItem(AConstant value): - switch (item.type) { - case REF(Type t): - if (item.type.isValueType()) { - assert t.IsEnum() || toType.equals(MSILType.OBJECT) - : item + " => "+ toType; - return coerce(load(item), toType); - } - assert (item.type.isValueType()) - || (item.type.isReferenceType() - && item.type.isSubtypeOf(toType)); - } - item.type = toType; - return item; - case ArgItem(_): - case LocalItem(_): - if (item.type.isSubtypeOf(toType)) { - item.type = toType; - return item; - } - break; - case CondItem(_, _, _): - if (item.type == MSILType.BOOL) - return item; - break; - } - return coerce(load(item), toType); - } - - /***/ - private void emitConvert(MSILType fromType, MSILType toType) { - switch (fromType) { - case REF(Type t): - if (t.IsValueType() && toType.isType(tc.OBJECT)) { - code.Emit(OpCodes.Box, t); - return; - } else if (t.IsEnum()) { - emitConvert(msilType(t.getUnderlyingType()), toType); - return; - } - } - if (fromType.isSubtypeOf(toType)) - return; - switch (toType) { - case BOOL: code.Emit(OpCodes.Conv_I4); return; // TODO: is this correct/best? - case I1: code.Emit(OpCodes.Conv_I1); return; - case I2: code.Emit(OpCodes.Conv_I2); return; - case I4: code.Emit(OpCodes.Conv_I4); return; - case I8: code.Emit(OpCodes.Conv_I8); return; - case R4: code.Emit(OpCodes.Conv_R4); return; - case R8: code.Emit(OpCodes.Conv_R8); return; - case CHAR: code.Emit(OpCodes.Conv_U2); return; - case REF(Type t): - if (t.IsEnum()) { - assert fromType.isType(t.getUnderlyingType()); - return; - } - break; - } - throw Debug.abort("emitConvert: " + fromType + " => " + toType - + "; fromType.isSubtypeOf(toType) = " - + fromType.isSubtypeOf(toType)); - } - - private static class LabelDescr { - final Label label; - final Ident[] params; - LabelDescr(Label label, Ident[] params) { - this.label = label; - this.params = params; - } - } - - private Item genApply(Tree fun, Tree[] args, MSILType resType) { - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - Item item = genApply0(fun, args, resType); - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - return item; - } - /** Generate the code for an Apply node */ - private Item genApply0(Tree fun, Tree[] args, MSILType resType) { - Symbol sym = fun.symbol(); - switch (fun) { - case Ident(_): - LabelDescr ld = (LabelDescr)sym2label.get(sym); - if (ld != null) { - assert ld.params.length == args.length - : ld.params.length + " != " + args.length; - lastExpr = false; - for (int i = 0; i < args.length; i++) - genLoad(args[i], msilType(args[i].type)); - for (int i = args.length - 1; i >= 0; i--) { - Item ident = gen(ld.params[i], msilType(ld.params[i])); - store(ident); - } - code.Emit(OpCodes.Br, ld.label); - unreachable = true; - MSILType retType = msilType(sym.info().resultType()); - Item i = retType == MSILType.VOID ? items.VoidItem() - : items.StackItem(retType); - return coerce(i, resType); - } - assert sym.isStatic() : Debug.show(sym); - - Primitive p = primitives.getPrimitive(sym); - switch (p) { - case UNBOX: - assert args.length == 1; - MSILType t = msilType(args[0].type); - Item i = genLoad(args[0], t); - if (!i.type.isValueType()) { - MethodInfo method = (MethodInfo)tc.getMethod(sym); - code.Emit(OpCodes.Call, method); - i = returnsVoid(method) ? items.VoidItem() - : items.StackItem(msilType(method.ReturnType)); - return coerce(i, resType); - } - if (sym == primitives.UNBOX_UVALUE) { - return items.VoidItem(); - } - return i; - } - MSILType convTo = primitiveConvert(sym); - if (convTo != null) { - assert args.length == 1; - genLoad(args[0], convTo); - return items.StackItem(convTo); - } - // Generate delegate's reverse view - if (sym.name == Names.view && - CLRTypes.instance().isDelegateType(resType.toType())) - { - assert args.length == 1 : Debug.show(sym); - return createDelegateFromFunction(args[0], resType); - } - - return check(invokeMethod(sym, args, resType, true)); - - case Select(Tree qualifier, _): - // scala.Any.== - if (sym == defs.ANY_EQEQ) { - return genEq(qualifier, args[0]); - } - // scala.Any.!= - if (sym == defs.ANY_BANGEQ) { - return negate(genEq(qualifier, args[0])); - } - // java.lang.String.substring(int start, int end) needs conversion - // to System.String.Substring(int start, int length) - if (sym == tc.SYM_SUBSTRING_INT_INT) { - assert args.length == 2; - genLoad(qualifier, MSILType.STRING); - genLoad(args[0], MSILType.I4); - code.Emit(OpCodes.Dup); - code.Emit(OpCodes.Neg); - genLoad(args[1], MSILType.I4); - code.Emit(OpCodes.Add); - code.Emit(OpCodes.Call, tc.SUBSTRING_INT_INT); - return coerce(items.StackItem(MSILType.STRING), resType); - } - - if (sym == tc.SYM_COMPARE_TO_IGNORE_CASE) { - assert args.length == 1; - genLoad(qualifier, MSILType.STRING); - genLoad(args[0], MSILType.STRING); - code.Emit(OpCodes.Ldc_I4_1); - code.Emit(OpCodes.Call, tc.COMPARE_TO_IGNORE_CASE); - return coerce(items.StackItem(MSILType.STRING), resType); - } - - if (isPrimitiveArrayOp(sym)) { - Primitive prim = primitives.getPrimitive(sym); - loadArgs(args, tc.getMethod(sym).GetParameters()); - Type elemType = getArrayElemType(prim); - switch (prim) { - case ZARRAY_LENGTH: case BARRAY_LENGTH: case SARRAY_LENGTH: - case CARRAY_LENGTH: case IARRAY_LENGTH: case LARRAY_LENGTH: - case FARRAY_LENGTH: case DARRAY_LENGTH: case OARRAY_LENGTH: - code.Emit(OpCodes.Ldlen); - return items.StackItem(MSILType.I4); - case NEW_ZARRAY: - case NEW_BARRAY: - case NEW_SARRAY: - case NEW_CARRAY: - case NEW_IARRAY: - case NEW_LARRAY: - case NEW_FARRAY: - case NEW_DARRAY: - //case NEW_OARRAY: - code.Emit(OpCodes.Newarr, elemType); - return items.StackItem(MSILType.ARRAY(msilType(elemType))); - case ZARRAY_GET: case BARRAY_GET: case SARRAY_GET: - case CARRAY_GET: case IARRAY_GET: case LARRAY_GET: - case FARRAY_GET: case DARRAY_GET: case OARRAY_GET: - MSILType mType = MSILArrayElemType(elemType); - emitLdelem(mType); - return items.StackItem(mType); - case ZARRAY_SET: case BARRAY_SET: case SARRAY_SET: - case CARRAY_SET: case IARRAY_SET: case LARRAY_SET: - case FARRAY_SET: case DARRAY_SET: case OARRAY_SET: - emitStelem(MSILArrayElemType(elemType)); - return items.VoidItem(); - } - } - - if (isPrimitiveOp(sym)) { - assert args.length <= 1; - Tree right = args.length > 0 ? args[0] : Tree.Empty; - return primitiveOp(primitives.getPrimitive(sym), - qualifier, right, resType); - } - - Symbol owner = sym.owner(); - Type t = tc.getType(owner); - assert t != null; - if (t.IsEnum()) { - Primitive enumOp = null; - if (sym.name == Names.EQ) enumOp = Primitive.EQ; - else if (sym.name == Names.NE) enumOp = Primitive.NE; - else if (sym.name == Names.LT) enumOp = Primitive.LT; - else if (sym.name == Names.LE) enumOp = Primitive.LE; - else if (sym.name == Names.GT) enumOp = Primitive.GT; - else if (sym.name == Names.GE) enumOp = Primitive.GE; - else if (sym.name == Names.OR) enumOp = Primitive.OR; - else if (sym.name == Names.AND) enumOp = Primitive.AND; - else if (sym.name == Names.XOR) enumOp = Primitive.XOR; - if (enumOp != null) { - assert args.length == 1; - return primitiveOp(enumOp, qualifier, args[0], resType); - } - } - - switch (qualifier.type) { - case TypeRef(_, _, _): - case SingleType(_, _): - case ThisType(_): - MethodBase method = tc.getMethod(sym); - assert method != null : Debug.show(sym); - boolean virtualCall = false; - if (!method.IsStatic() || becomesStatic(sym)) { - // FIXME: after the Super attribution is correct - switch (qualifier) { - case Super(_, _): - load(items.SelfItem(tc.getType(currentClass))); - break; - default: - genAddr(qualifier, msilType(qualifier)); - virtualCall = !msilType(qualifier).isValueType(); - } - } - return check(invokeMethod(sym, args, resType, - virtualCall || method.IsAbstract())); - - default: - throw Debug.abort(Debug.show(fun)); - } // switch(qualifier.type) - - case TypeApply(Tree tfun, Tree[] targs): - final Symbol tsym = tfun.symbol(); - if (primitives.isPrimitive(tsym)) { - return primitiveOp(primitives.getPrimitive(tsym), - ((Select)tfun).qualifier, - targs[0], resType); - } - throw Debug.abort(Debug.show(fun)); - - default: - throw Debug.abort(Debug.show(fun)); - } // switch (fun) - } //genApply() - - - /** Generate code for scala's '==' */ - private Item genEq(Tree left, Tree right) { - LocalBuilder tmpLocal = (LocalBuilder)locals.get(defs.ANY_EQEQ); - if (tmpLocal == null) { - tmpLocal = code.DeclareLocal(tc.OBJECT); - locals.put(defs.ANY_EQEQ, tmpLocal); - } - Label l1 = code.DefineLabel(), l2 = code.DefineLabel(); - genLoad(left, MSILType.OBJECT); - genLoad(right, MSILType.OBJECT); - emitStloc(tmpLocal); - code.Emit(OpCodes.Dup); - code.Emit(OpCodes.Ldnull); - code.Emit(OpCodes.Bne_Un, l1); - emitLdloc(tmpLocal); - code.Emit(OpCodes.Ceq); - code.Emit(OpCodes.Br, l2); - code.MarkLabel(l1); - emitLdloc(tmpLocal); - code.Emit(OpCodes.Callvirt, tc.OBJECT_EQUALS); - code.MarkLabel(l2); - return items.StackItem(MSILType.BOOL); - } - - /** Is it a primitive (bot not an array) operation*/ - private boolean isPrimitiveOp(Symbol sym) { - switch (primitives.getPrimitive(sym)) { - case POS: case NEG: case NOT: - case ADD: case SUB: case MUL: case DIV: case MOD: - case OR: case XOR: case AND: - case LSL: case LSR: case ASR: - case ID: case NI: case EQ: case NE: case LT: case LE: case GT: case GE: - case ZNOT: case ZOR: case ZAND: - case IS: case AS: - case CONCAT: - case THROW: - case SYNCHRONIZED: - return true; - default: - return false; - } - } - - /* Is this a primitive Array operation. */ - private boolean isPrimitiveArrayOp(Symbol sym) { - switch (primitives.getPrimitive(sym)) { - case NEW_ZARRAY: case NEW_BARRAY: case NEW_SARRAY: - case NEW_CARRAY: case NEW_IARRAY: case NEW_LARRAY: - case NEW_FARRAY: case NEW_DARRAY: //case NEW_OARRAY: - case ZARRAY_LENGTH: case BARRAY_LENGTH: case SARRAY_LENGTH: - case CARRAY_LENGTH: case IARRAY_LENGTH: case LARRAY_LENGTH: - case FARRAY_LENGTH: case DARRAY_LENGTH: case OARRAY_LENGTH: - case ZARRAY_GET: case BARRAY_GET: case SARRAY_GET: - case CARRAY_GET: case IARRAY_GET: case LARRAY_GET: - case FARRAY_GET: case DARRAY_GET: case OARRAY_GET: - case ZARRAY_SET: case BARRAY_SET: case SARRAY_SET: - case CARRAY_SET: case IARRAY_SET: case LARRAY_SET: - case FARRAY_SET: case DARRAY_SET: case OARRAY_SET: - return true; - default: - return false; - } - } - - /* Is this a primitive conversion operation. */ - private MSILType primitiveConvert(Symbol sym) { - switch (primitives.getPrimitive(sym)) { - case B2B: case S2B: case C2B: case I2B: case L2B: case F2B: case D2B: - return MSILType.I1; - case B2S: case S2S: case C2S: case I2S: case L2S: case F2S: case D2S: - return MSILType.I2; - case B2C: case S2C: case C2C: case I2C: case L2C: case F2C: case D2C: - return MSILType.CHAR; - case B2I: case S2I: case C2I: case I2I: case L2I: case F2I: case D2I: - return MSILType.I4; - case B2L: case S2L: case C2L: case I2L: case L2L: case F2L: case D2L: - return MSILType.I8; - case B2F: case S2F: case C2F: case I2F: case L2F: case F2F: case D2F: - return MSILType.R4; - case B2D: case S2D: case C2D: case I2D: case L2D: case F2D: case D2D: - return MSILType.R8; - default: - return null; - } - } - - /* Generate code for primitive operations. */ - private Item primitiveOp(Primitive op, Tree left, Tree right, MSILType resType) - { - // treat some special cases - switch (op) { - - case CONCAT: - genLoad(left, MSILType.OBJECT); - genLoad(right, MSILType.OBJECT); - code.Emit(OpCodes.Call, tc.CONCAT_OBJECT_OBJECT); - return items.StackItem(MSILType.STRING); - - case ADD: - if (tc.getType(right.type) == tc.STRING) { - // TODO: check why this never gets printed - genLoad(left, MSILType.OBJECT); - genLoad(right, MSILType.OBJECT); - code.Emit(OpCodes.Call, tc.CONCAT_OBJECT_OBJECT); - return items.StackItem(MSILType.STRING); - } - break; - - case IS: - genLoad(left, MSILType.OBJECT); - final Type type = tc.getType(right.type); - code.Emit(OpCodes.Isinst, type); - return mkCond(items.StackItem(msilType(type))); - - case AS: - MSILType mltype = msilType(left); - Item item = genLoad(left, mltype); - final Type rtype = tc.getType(right.type); - final MSILType mrtype = msilType(rtype); - if (mltype.isEnum()) { - MSILType ptype = unboxValueType(mrtype); - if (ptype != null) { - MSILType uetype = msilType(mltype.getUnderlyingType()); - emitConvert(uetype, ptype); - return items.StackItem(ptype); - } - //} else if (!item.type.equals(mrtype) && !(rtype == tc.OBJECT)) { - } else if (!item.type.isSubtypeOf(mrtype) && !(rtype == tc.OBJECT)) { - if (rtype.IsValueType()) { - code.Emit(OpCodes.Unbox, rtype); - if (rtype.IsEnum()) - emitLdind(rtype.getUnderlyingType()); - else - code.Emit(OpCodes.Ldobj, rtype); - } else { - code.Emit(OpCodes.Castclass, rtype); - } - } - return items.StackItem(mrtype); - - case SYNCHRONIZED: - // TODO: reuse temporary local variable whenever possible - LocalBuilder tmp = code.DeclareLocal(tc.OBJECT); - genLoad(left, MSILType.OBJECT); - emitStloc(tmp); - emitLdloc(tmp); - code.Emit(OpCodes.Call, tc.MONITOR_ENTER); - genLoad(right, MSILType.OBJECT); - emitLdloc(tmp); - code.Emit(OpCodes.Call, tc.MONITOR_EXIT); - return items.StackItem(MSILType.OBJECT); - } - - Item iLeft = null; - MSILType tleft = msilType(left); - switch (left) { - case Apply(Tree fun , Tree[] args): - Primitive p = primitives.getPrimitive(fun.symbol()); - switch (p) { - case BOX: - assert args.length == 1; - iLeft = gen(args[0], msilType(args[0])); - break; - default: - iLeft = gen(left, tleft); - } - break; - default: - iLeft = gen(left, tleft); - } - - switch (op) { - case THROW: - load(iLeft); - code.Emit(OpCodes.Throw); -// code.Emit(OpCodes.Ldnull); -// return items.StackItem(MSILType.NULL); - //return coerce(loadNull(), resType); - return loadNull(); - - case POS: return load(coerce(iLeft, resType)); - case NEG: - iLeft = load(coerce(iLeft, resType)); - code.Emit(OpCodes.Neg); - return iLeft; - case NOT: - iLeft = load(coerce(iLeft, resType)); - code.Emit(OpCodes.Not); - return iLeft; - case ZNOT: - return negate(mkCond(iLeft)); - case ZOR: - Item.CondItem lcond = mkCond(iLeft), rcond = null; - Chain success = lcond.success, failure = lcond.failure; - switch (lcond.test) { - case True: - return lcond; - case False: - return mkCond(gen(right, MSILType.BOOL)); - case And(Test t): - success = (success != null) ? - success : new Chain(code.DefineLabel(), null); - branch(negate(lcond.test), success); - resolve(failure); - failure = null; - break; - default: - success = (success != null) ? - success : new Chain(code.DefineLabel(), null); - branch(negate(lcond.test), success); - } - rcond = mkCond((gen(right, MSILType.BOOL))); - rcond = items.CondItem(Test.Or(rcond.test), - merge(success, rcond.success), - merge(failure, rcond.failure)); - return rcond; - case ZAND: - Item.CondItem lcond = mkCond(iLeft), rcond = null; - Chain success = lcond.success, failure = lcond.failure; - switch (lcond.test) { - case False: - return lcond; - case True: - return mkCond(gen(right, MSILType.BOOL)); - case Or(Test t): - failure = (failure != null) ? - failure : new Chain(code.DefineLabel(), null); - branch(lcond.test, failure); - resolve(success); - success = null; - break; - default: - failure = (failure != null) ? - failure : new Chain(code.DefineLabel(), null); - branch(lcond.test, failure); - } - rcond = mkCond(gen(right, MSILType.BOOL)); - rcond = items.CondItem(Test.And(rcond.test), - merge(success, rcond.success), - merge(failure, rcond.failure)); - return rcond; - } - - MSILType toType = MSILType.arithmCoercion(iLeft.type.asPrimitive(), - primitiveType(right.type)); - load(coerce(iLeft, toType)); - genLoad(right, toType); - Item res = null; - switch (op) { - case ADD: code.Emit(OpCodes.Add); res = items.StackItem(toType); break; - case SUB: code.Emit(OpCodes.Sub); res = items.StackItem(toType); break; - case MUL: code.Emit(OpCodes.Mul); res = items.StackItem(toType); break; - case DIV: code.Emit(OpCodes.Div); res = items.StackItem(toType); break; - case MOD: code.Emit(OpCodes.Rem); res = items.StackItem(toType); break; - - case OR: code.Emit(OpCodes.Or); res = items.StackItem(toType); break; - case XOR: code.Emit(OpCodes.Xor); res = items.StackItem(toType); break; - case AND: code.Emit(OpCodes.And); res = items.StackItem(toType); break; - - case LSL: code.Emit(OpCodes.Shl); res = items.StackItem(toType); break; - case LSR: code.Emit(OpCodes.Shr); res = items.StackItem(toType); break; - case ASR: code.Emit(OpCodes.Shr_Un); res = items.StackItem(toType); break; - - case ID: case EQ: // FIXME?: should ID be treated as EQ? - res = items.CondItem(Test.Binary(Test.EQ, toType), null, null); - break; - case NI: case NE: // FIXME?: should NI be treated as NE? - res = items.CondItem(Test.Binary(Test.NE, toType), null, null); - break; - case LT: - res = items.CondItem(Test.Binary(Test.LT_IS, toType), null, null); - break; - case LE: - res = items.CondItem(Test.Binary(Test.LE_IS, toType), null, null); - break; - case GT: - res = items.CondItem(Test.Binary(Test.GT_IS, toType), null, null); - break; - case GE: - res = items.CondItem(Test.Binary(Test.GE_IS, toType), null, null); - break; - default: - throw Debug.abort(Debug.show(op)); - } - - return coerce(res, resType); - } - - /* - * Load function arguments on the stack. - */ - private void loadArgs(Tree[] args, ParameterInfo[] params) { - for (int i = 0; i < args.length; i++) { - MSILType toType = msilType(params[i].ParameterType); //msilType(args[i].type); - genLoad(args[i], toType); - } - } - - /* - * Tells if a non-static method is translated to a static one. - */ - private boolean becomesStatic(Symbol sym) { - MethodBase method = tc.getMethod(sym); - return !sym.isStatic() && method.IsStatic(); - } - - /* - * Generate code for method invocation - */ - private Item invokeMethod(Symbol fun, Tree[] args, MSILType resType, - boolean virtualCall) { - MethodBase method = tc.getMethod(fun); - assert method != null : "Coudn't resolve method: " + Debug.show(fun); - Item res = null; - if (method.IsStatic()) { - ParameterInfo[] params = method.GetParameters(); - if (becomesStatic(fun)) { - assert params.length == args.length + 1; - ParameterInfo[] newParams = new ParameterInfo[params.length - 1]; - for (int i = 0; i < newParams.length; i++) - newParams[i] = params[i + 1]; - params = newParams; - } - loadArgs(args, params); - code.Emit(OpCodes.Call, (MethodInfo)method); - res = returnsVoid(method) ? items.VoidItem() : - items.StackItem(resType); - } else if (method.IsConstructor()) { - // used only for calls to super constructor - //emitThis(); - loadArgs(args, method.GetParameters()); - code.Emit(OpCodes.Call, (ConstructorInfo)method); - res = items.VoidItem(); - } else { - loadArgs(args, method.GetParameters()); - if (enableTailCalls && lastExpr /*&& method == currentMethod*/) - code.Emit(OpCodes.Tailcall); - code.Emit(virtualCall ? OpCodes.Callvirt : OpCodes.Call, - (MethodInfo)method); - res = returnsVoid(method) ? items.VoidItem() : items.StackItem(resType); - } - CLRTypes clrt = CLRTypes.instance(); - if (returnsVoid(fun) && !returnsVoid(method) - && method != clrt.DELEGATE_COMBINE - && method != clrt.DELEGATE_REMOVE) - { - res = drop(res); - } - return res; - } - - private Item createDelegateFromFunction(Tree fun, MSILType type) { - Item ifun = genLoad(fun, msilType(fun.type)); - // Get the apply function of the delegate object - Symbol funSym = tc.getSymbol(ifun.type.toType()); - Symbol applySym = funSym.lookup(Names.apply); - MethodInfo apply = (MethodInfo) tc.getDelegateApplyMethod(applySym); - - // Get the (object, native int) constructor of the delegate type - Type delegateType = type.toType(); - ConstructorInfo delegCtor = delegateType.GetConstructor( - new Type[]{tc.OBJECT, Type.GetType("System.IntPtr")}); - - // Duplicate the object on the stack; we need its apply method - // and Ldvirtftn uses one element. - code.Emit(OpCodes.Dup); - code.Emit(OpCodes.Ldvirtftn, apply); - - // Create a new delegate; this uses up the element duplicated above. - code.Emit(OpCodes.Newobj, delegCtor); - - return items.StackItem(type); - } - - /* - * Returns the MSILType that corresponds to the given scala.symtab.Type - */ - private MSILType msilType(scalac.symtab.Type type) { - return type.symbol() == defs.ALLREF_CLASS ? MSILType.NULL - : msilType(tc.getType(type)); - } - - /* - * Also used from class ItemFactory. - */ - MSILType msilType(Type type) { - return MSILType.fromType(type); - } - - /* - * Returns the MSILType from the type atribute of a tree node - */ - private MSILType msilType(Tree t) { - return msilType(t.type); - } - - /* - * Treat the scala boxed types as a primitive type - */ - private MSILType primitiveType(scalac.symtab.Type type) { - MSILType mtype = msilType(type); - switch (mtype) { - case REF(Type t): - return unboxValueType(mtype).asPrimitive(); - //case NULL: - case ARRAY(_): - throw Debug.abort("cannot convert " + mtype); - default: - return mtype; - } - } - - private MSILType unboxValueType(MSILType type) { - switch (type) { - case REF(Type t): - if (t == tc.SCALA_BYTE) return MSILType.I1; - if (t == tc.SCALA_SHORT) return MSILType.I2; - if (t == tc.SCALA_INT) return MSILType.I4; - if (t == tc.SCALA_LONG) return MSILType.I8; - if (t == tc.SCALA_FLOAT) return MSILType.R4; - if (t == tc.SCALA_DOUBLE) return MSILType.R8; - if (t == tc.SCALA_CHAR) return MSILType.CHAR; - //if (t == tc.SCALA_UNIT) return MSILType.VOID; - if (t == tc.SCALA_BOOLEAN) return MSILType.BOOL; - } - return type; - } - - /* - * Provides a translation for some types when used as array elements. - */ - private MSILType MSILArrayElemType(Type type) { - MSILType mtype = msilType(type); - switch (mtype) { - case BOOL: return MSILType.I1; - case CHAR: return MSILType.I4; - default: return mtype; - } - } - - /* - * - */ - private Type getArrayElemType(Primitive p) { - switch (p) { - case NEW_ZARRAY: case ZARRAY_LENGTH: case ZARRAY_GET: case ZARRAY_SET: - return tc.BOOLEAN; - case NEW_BARRAY: case BARRAY_LENGTH: case BARRAY_GET: case BARRAY_SET: - return tc.BYTE; - case NEW_SARRAY: case SARRAY_LENGTH: case SARRAY_GET: case SARRAY_SET: - return tc.SHORT; - case NEW_CARRAY: case CARRAY_LENGTH: case CARRAY_GET: case CARRAY_SET: - return tc.CHAR; - case NEW_IARRAY: case IARRAY_LENGTH: case IARRAY_GET: case IARRAY_SET: - return tc.INT; - case NEW_LARRAY: case LARRAY_LENGTH: case LARRAY_GET: case LARRAY_SET: - return tc.LONG; - case NEW_FARRAY: case FARRAY_LENGTH: case FARRAY_GET: case FARRAY_SET: - return tc.FLOAT; - case NEW_DARRAY: case DARRAY_LENGTH: case DARRAY_GET: case DARRAY_SET: - return tc.DOUBLE; - case NEW_OARRAY: case OARRAY_LENGTH: case OARRAY_GET: case OARRAY_SET: - return tc.OBJECT; - } - throw Debug.abort("unknown primitive " + Debug.show(p)); - } - - /* - * Emit code to load an array elemnt of the given type on the stack. - */ - private Item emitLdelem(MSILType type) { - switch (type) { - case I1: code.Emit(OpCodes.Ldelem_I1); break; - case I2: code.Emit(OpCodes.Ldelem_I2); break; - case I4: code.Emit(OpCodes.Ldelem_I4); break; - case I8: code.Emit(OpCodes.Ldelem_I8); break; - case R4: code.Emit(OpCodes.Ldelem_R4); break; - case R8: code.Emit(OpCodes.Ldelem_R8); break; - case ARRAY(_): - case REF(_): - code.Emit(OpCodes.Ldelem_Ref); break; - } - return items.StackItem(type); - } - - /* - * Emit code to strore the value at the top of the stack from the given type - * to an array. - */ - private Item emitStelem(MSILType type) { - switch (type) { - case I1: code.Emit(OpCodes.Stelem_I1); break; - case I2: code.Emit(OpCodes.Stelem_I2); break; - case I4: code.Emit(OpCodes.Stelem_I4); break; - case I8: code.Emit(OpCodes.Stelem_I8); break; - case R4: code.Emit(OpCodes.Stelem_R4); break; - case R8: code.Emit(OpCodes.Stelem_R8); break; - case ARRAY(_): - case REF(_): - code.Emit(OpCodes.Stelem_Ref); break; - } - return items.StackItem(type); - } - - private Item.LiteralItem mkLiteral(MSILType type, Object value) { - LiteralItem item = null; - if (value instanceof Integer) - item = items.LiteralItem(AConstant.INT(((Number)value).intValue())); - else if (value instanceof Long) - item = items.LiteralItem(AConstant.LONG(((Number)value).longValue())); - else if (value instanceof Float) - item = items.LiteralItem(AConstant.FLOAT(((Number)value).floatValue())); - else if (value instanceof Double) - item = items.LiteralItem(AConstant.DOUBLE(((Number)value).doubleValue())); - else throw Debug.abort(); - item.type = type; - return item; - } - - private void emitLdarg(int slot) { - assert slot >= 0; - switch (slot) { - case 0: code.Emit(OpCodes.Ldarg_0); break; - case 1: code.Emit(OpCodes.Ldarg_1); break; - case 2: code.Emit(OpCodes.Ldarg_2); break; - case 3: code.Emit(OpCodes.Ldarg_3); break; - default: - code.Emit(slot < 256 ? OpCodes.Ldarg_S : OpCodes.Ldarg, slot); - } - } - - private void emitLdarga(int slot) { - code.Emit(slot < 256 ? OpCodes.Ldarga_S : OpCodes.Ldarga, slot); - } - - private void emitLdloc(LocalBuilder loc) { - switch (loc.slot) { - case 0: code.Emit(OpCodes.Ldloc_0); break; - case 1: code.Emit(OpCodes.Ldloc_1); break; - case 2: code.Emit(OpCodes.Ldloc_2); break; - case 3: code.Emit(OpCodes.Ldloc_3); break; - default: - code.Emit(loc.slot < 256 ? OpCodes.Ldloc_S : OpCodes.Ldloc, loc); - } - } - - private void emitLdloca(LocalBuilder loc) { - code.Emit(loc.slot < 256 ? OpCodes.Ldloca_S : OpCodes.Ldloca, loc); - } - - private void emitStloc(LocalBuilder loc) { - switch (loc.slot) { - case 0: code.Emit(OpCodes.Stloc_0); break; - case 1: code.Emit(OpCodes.Stloc_1); break; - case 2: code.Emit(OpCodes.Stloc_2); break; - case 3: code.Emit(OpCodes.Stloc_3); break; - default: - code.Emit(loc.slot < 256 ? OpCodes.Stloc_S : OpCodes.Stloc, loc); - } - } - - /* - * Load the value of an item on the stack. - */ - private Item load(Item that) { - switch (that) { - case VoidItem(): - return that; - - case StackItem(): - return (StackItem) that; - - case LiteralItem(AConstant value): - return loadLiteral(value, that.type); - - case SelfItem(): - emitThis(); - return items.StackItem(that.type); - - case ArgItem(int slot): - emitLdarg(slot); - return items.StackItem(that.type); - - case LocalItem(LocalBuilder local): - emitLdloc(local); - return items.StackItem(that.type); - - case StaticItem(FieldInfo field): - assert !field.IsLiteral() : field.toString(); - code.Emit(OpCodes.Ldsfld, field); - return items.StackItem(that.type); - - case SelectItem(Item qual, FieldInfo field): - Item i = load(qual); - code.Emit(OpCodes.Ldfld, field); - return items.StackItem(that.type); - - case CondItem(Test test, Chain success, Chain failure): - load(test); - switch (test) { - case Or(_): - case And(_): - Label exit = null; - /*if (lastExpr) - code.Emit(OpCodes.Ret); - else */ { - exit = code.DefineLabel(); - if (!unreachable) - code.Emit(OpCodes.Br, exit); - } - if (failure != null) { - resolve(failure); - load(FALSE_ITEM); - if (success != null) { - /*if (lastExpr) - code.Emit(OpCodes.Ret); - else*/ - if (!unreachable) - code.Emit(OpCodes.Br, exit); - } - } - if (success != null) { - resolve(success); - load(TRUE_ITEM); - } - resolve(exit); - break; - } - return items.StackItem(MSILType.BOOL); - - default: - throw Debug.abort("load item: " + that); - } - } - - - /* - * Load the value of a test on the stack. - */ - private void load(Test test) { - switch (test) { - case False: - code.Emit(OpCodes.Ldc_I4_0); - break; - case True: - code.Emit(OpCodes.Ldc_I4_1); - break; - case Bool(boolean value): - if (value) negate_load(); - break; - case Binary(int opcode, MSILType type): - code.Emit(load(opcode)); - if (negate_load(opcode)) negate_load(); - break; - case And(Test t): - load(t); - break; - case Or(Test t): - load(t); - break; - default: - throw Debug.abort(test.getClass().getName()); - } - } - - /* - * Load the value of an ALiteral on the stack. - */ - private Item.StackItem loadLiteral(AConstant constant) { - switch (constant) { - case UNIT: - return loadUnit(); - case BOOLEAN(boolean value): - return loadBool(value); - case BYTE(byte value): - return loadI4(value); - case SHORT(short value): - return loadI4(value); - case CHAR(char value): - loadI4(value); - return items.StackItem(MSILType.CHAR); - case INT(int value): - return loadI4(value); - case LONG(long value): - return loadI8(value); - case FLOAT(float value): - return loadR4(value); - case DOUBLE(double value): - return loadR8(value); - case STRING(String value): - return loadString(value); - case NULL: - return loadNull(); - default: - throw Debug.abort("illegal case", constant); - } - } - - /* - * Load the value of an ALiteral coerced to the given type. - */ - private Item loadLiteral(AConstant constant, MSILType ofType) { - switch (ofType) { - case I1: - case I2: - case I4: - loadI4(constant.intValue()); return items.StackItem(MSILType.I4); - case CHAR: - loadI4(constant.intValue()); return items.StackItem(MSILType.CHAR); - case I8: loadI8(constant.longValue()); return items.StackItem(ofType); - case R4: loadR4(constant.floatValue()); return items.StackItem(ofType); - case R8: loadR8(constant.doubleValue()); return items.StackItem(ofType); - case REF(Type t): - //assert t == tc.STRING || ofType.isValueType() : "" + ofType; - return coerce(loadLiteral(constant), ofType); - default: - return coerce(loadLiteral(constant), ofType); - } - } - - /* - * Load boxed scala.Unit on the stack. - */ - private Item.StackItem loadUnit() { - code.Emit(OpCodes.Call, tc.RUNTIME_BOX_UNIT); - return items.StackItem(msilType(tc.RUNTIME_BOX_UNIT.ReturnType)); - } - - /* - * Load a boolean value on the stack. - */ - private Item.StackItem loadBool(boolean value) { - code.Emit(value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); - return items.StackItem(MSILType.BOOL); - } - - /* - * Load a 32-bit integer literal on the stack. - */ - private Item.StackItem loadI4(int value) { - switch (value) { - case -1:code.Emit(OpCodes.Ldc_I4_M1); break; - case 0: code.Emit(OpCodes.Ldc_I4_0); break; - case 1: code.Emit(OpCodes.Ldc_I4_1); break; - case 2: code.Emit(OpCodes.Ldc_I4_2); break; - case 3: code.Emit(OpCodes.Ldc_I4_3); break; - case 4: code.Emit(OpCodes.Ldc_I4_4); break; - case 5: code.Emit(OpCodes.Ldc_I4_5); break; - case 6: code.Emit(OpCodes.Ldc_I4_6); break; - case 7: code.Emit(OpCodes.Ldc_I4_7); break; - case 8: code.Emit(OpCodes.Ldc_I4_8); break; - default: - if (value >= -128 && value <= 127) - code.Emit(OpCodes.Ldc_I4_S, value); - else - code.Emit(OpCodes.Ldc_I4, value); - } - return items.StackItem(MSILType.I4); - } - - /* - * Load a 64-bit integer value on the stack. - */ - private Item.StackItem loadI8(long value) { - code.Emit(OpCodes.Ldc_I8, value); - return items.StackItem(MSILType.I8); - } - - /* - * Load a single precision floating point value on the stack. - */ - private Item.StackItem loadR4(float value) { - code.Emit(OpCodes.Ldc_R4, value); - return items.StackItem(MSILType.R4); - } - - /* - * Load a double precision floating point value on the stack. - */ - private Item.StackItem loadR8(double value) { - code.Emit(OpCodes.Ldc_R8, value); - return items.StackItem(MSILType.R8); - } - - /* - * Load a string reference on the stack. - */ - private Item.StackItem loadString(String value) { - code.Emit(OpCodes.Ldstr, value); - return items.StackItem(MSILType.STRING); - } - - /* - * Load the 'null' reference on the stack. - */ - private Item.StackItem loadNull() { - code.Emit(OpCodes.Ldnull); - return items.StackItem(MSILType.NULL); - } - - private void emitLdind(Type type) { - if (type == tc.BYTE) - code.Emit(OpCodes.Ldind_I1); - else if (type == tc.SHORT) - code.Emit(OpCodes.Ldind_I2); - else if (type == tc.INT) - code.Emit(OpCodes.Ldind_I4); - else if (type == tc.LONG) - code.Emit(OpCodes.Ldind_I8); - else - throw Debug.abort("emitLdind failed", type); - } - - - /* - * Store the value on the stack to the location specified by the item. - */ - private Item store(Item that) { - switch (that) { - case ArgItem(int slot): - code.Emit(OpCodes.Starg, slot); - break; - - case LocalItem(LocalBuilder local): - emitStloc(local); - break; - - case StaticItem(FieldInfo field): - assert !field.IsLiteral(); - code.Emit(OpCodes.Stsfld, field); - break; - - case SelectItem(Item qual, FieldInfo field): - load(qual); - code.Emit(OpCodes.Stfld, field); - break; - - default: - throw Debug.abort("Cannot store item: " + that); - } - return items.VoidItem(); - } - - - /* - * Discard the item. - */ - private Item drop(Item that) { - switch (that) { - case VoidItem(): - case SelfItem(): - case LiteralItem(_): - case ArgItem(_): - case LocalItem(_): - case StaticItem(_): - break; - case StackItem(): - code.Emit(OpCodes.Pop); - break; - case SelectItem(Item qual, _): - drop(qual); - break; - case CondItem(Test test, _, _): - switch (test) { - case False: - case True: - break; - case Bool(_): - code.Emit(OpCodes.Pop); - break; - case And(_): - case Or(_): - drop(load(that)); - break; - case Binary(_, _): - code.Emit(OpCodes.Pop); - code.Emit(OpCodes.Pop); - break; - default : - throw Debug.abort(that.getClass().getName()); - } - break; - default: - drop(load(that)); - } - return items.VoidItem(); - } - - /* - * Generate a condition corresponding to the given item. - */ - private Item.CondItem mkCond(Item that) { - switch (that) { - case CondItem(_, _, _): return (Item.CondItem) that; - default: - load(that); - return items.CondItem(Test.Bool(false), null, null); - } - } - - // load the address of a value type item; - // for reference types load a reference - private Item genAddr(Tree tree, MSILType toType) { - Item item = gen(tree, toType); - if (!item.type.isValueType()) - return load(item); - switch (item) { - case ArgItem(int slot): - emitLdarga(slot); - break; - case LocalItem(LocalBuilder local): - emitLdloca(local); - break; - case StaticItem(FieldInfo field): - if (field.IsInitOnly()) { - load(item); - genLocalAddr(field.FieldType); - } else - code.Emit(OpCodes.Ldsflda, field); - break; - case SelectItem(Item qual, FieldInfo field): - if (field.IsInitOnly()) { - load(item); - genLocalAddr(field.FieldType); - } else { - load(qual); - code.Emit(OpCodes.Ldflda, field); - } - break; - case StackItem(): - genLocalAddr(item.type.toType()); - break; - default: - throw Debug.abort(item.toString()); - } - return items.StackItem(toType); - } - - private void genLocalAddr(Type localType) { - assert localType.IsValueType() : localType.toString(); - LocalBuilder tmpLocal = (LocalBuilder)locals.get(localType); - if (tmpLocal == null) { - tmpLocal = code.DeclareLocal(localType); - locals.put(localType, tmpLocal); - } - emitStloc(tmpLocal); - emitLdloca(tmpLocal); - } - - /* - * Negate a condition. - */ - private Item.CondItem negate(Item item) { - Item.CondItem cond = mkCond(item); - // swap the failure and success chains - //return items.CondItem(negate(cond.test), cond.success, cond.failure); - return items.CondItem(negate(cond.test), cond.failure, cond.success); - } - - /* - * Emit code to negate a boolean value on the stack. - */ - private void negate_load() { - code.Emit(OpCodes.Ldc_I4_1); - code.Emit(OpCodes.Xor); - } - - /* - * Negate a test. - */ - private Test negate(Test that) { - switch (that) { - - case False: - return Test.True; - - case True: - return Test.False; - - case Bool(boolean value): - return Test.Bool(!value); - - case And(Test test): - return Test.Or(negate(test)); - - case Or(Test test): - return Test.And(negate(test)); - - case Binary(int opcode, MSILType type): - return Test.Binary(negate(opcode), type); - - default: - throw Debug.abort(that.getClass().getName()); - } - } - - /* - * Emit code for the appropriate branch. - */ - private Label branch(Test test, Chain chain) { - assert chain != null; - Label label = chain.label; - switch (test) { - case False: - code.Emit(OpCodes.Br, label); - return label; - case True: - return null; - case Bool(boolean value): - code.Emit(value ? OpCodes.Brtrue : OpCodes.Brfalse, label); - return label; - case And(Test t): - return branch(t, chain); - case Or(Test t): - return branch(t, chain); - case Binary(int opcode, MSILType type): - code.Emit(branch(negate(opcode)), label); - return label; - default: - throw Debug.abort(); - } - } - - /* - * Merge two label chains. - */ - private static Chain merge(Chain c1, Chain c2) { - if (c1 == null) return c2; - if (c2 == null) return c1; - Chain c = c1; - for(; c.next != null; c = c.next) ; - c.next = c2; - return c1; - } - - /* - * Resolve all labels int the chain to the current position in the code. - */ - private void resolve(Chain c) { - for (; c != null; c = c.next) - code.MarkLabel(c.label); - } - - /* - * Resolve a label to the current position in the code. - */ - private void resolve(Label l) { - if (l != null) - code.MarkLabel(l); - } - - /* - * - */ - private static boolean negate_load(int opcode) { - switch (opcode) { - case Test.LT_IS: return false; - case Test.LE_IS: return true; - case Test.GT_IS: return false; - case Test.GE_IS: return true; - case Test.LT_IU: return false; - case Test.LE_IU: return true; - case Test.GT_IU: return false; - case Test.GE_IU: return true; - case Test.LT_RO: return false; - case Test.LE_RO: return true; - case Test.GT_RO: return false; - case Test.GE_RO: return true; - case Test.LT_RU: return false; - case Test.LE_RU: return true; - case Test.GT_RU: return false; - case Test.GE_RU: return true; - case Test.EQ : return false; - case Test.NE : return true; - default : throw Debug.abort("" + opcode); - } - } - - /* - * - */ - private static OpCode load(int opcode) { - switch (opcode) { - case Test.LT_IS: return OpCodes.Clt; - case Test.LE_IS: return OpCodes.Cgt; // negate - case Test.GT_IS: return OpCodes.Cgt; - case Test.GE_IS: return OpCodes.Clt; // negate - case Test.LT_IU: return OpCodes.Clt_Un; - case Test.LE_IU: return OpCodes.Cgt_Un; // negate - case Test.GT_IU: return OpCodes.Cgt_Un; - case Test.GE_IU: return OpCodes.Clt_Un; // negate - case Test.LT_RO: return OpCodes.Clt; - case Test.LE_RO: return OpCodes.Cgt_Un; // negate - case Test.GT_RO: return OpCodes.Cgt; - case Test.GE_RO: return OpCodes.Clt_Un; // negate - case Test.LT_RU: return OpCodes.Clt_Un; - case Test.LE_RU: return OpCodes.Cgt; // negate - case Test.GT_RU: return OpCodes.Cgt_Un; - case Test.GE_RU: return OpCodes.Clt; // negate - case Test.EQ : return OpCodes.Ceq; - case Test.NE : return OpCodes.Ceq; // negate - default : throw Debug.abort("" + opcode); - } - } - - /* - * - */ - private static int negate(int opcode) { - switch (opcode) { - case Test.LT_IS: return Test.GE_IS; - case Test.LE_IS: return Test.GT_IS; - case Test.GT_IS: return Test.LE_IS; - case Test.GE_IS: return Test.LT_IS; - case Test.LT_IU: return Test.GE_IU; - case Test.LE_IU: return Test.GT_IU; - case Test.GT_IU: return Test.LE_IU; - case Test.GE_IU: return Test.LT_IU; - case Test.LT_RO: return Test.GE_RU; - case Test.LE_RO: return Test.GT_RU; - case Test.GT_RO: return Test.LE_RU; - case Test.GE_RO: return Test.LT_RU; - case Test.LT_RU: return Test.GE_RO; - case Test.LE_RU: return Test.GT_RO; - case Test.GT_RU: return Test.LE_RO; - case Test.GE_RU: return Test.LT_RO; - case Test.EQ : return Test.NE; - case Test.NE : return Test.EQ; - default : throw Debug.abort("" + opcode); - } - } - - /* - * - */ - private static OpCode branch(int opcode) { - switch (opcode) { - case Test.LT_IS: - case Test.LT_RO: return OpCodes.Blt; - case Test.LE_IS: - case Test.LE_RO: return OpCodes.Ble; - case Test.GT_IS: - case Test.GT_RO: return OpCodes.Bgt; - case Test.GE_IS: - case Test.GE_RO: return OpCodes.Bge; - case Test.LT_IU: - case Test.LT_RU: return OpCodes.Blt_Un; - case Test.LE_IU: - case Test.LE_RU: return OpCodes.Ble_Un; - case Test.GT_IU: - case Test.GT_RU: return OpCodes.Bgt_Un; - case Test.GE_IU: - case Test.GE_RU: return OpCodes.Bge_Un; - case Test.EQ : return OpCodes.Beq; - case Test.NE : return OpCodes.Bne_Un; - default : throw Debug.abort("" + opcode); - } - } - - //########################################################################## -} // class GenMSIL - -/** - * Represents the supported types of the CLR. - */ -final class MSILType { - public case I1; - public case I2; - public case U2; - public case I4; - public case I8; - public case R4; - public case R8; - public case BOOL; - public case CHAR; - public case VOID; - public case NULL; - public case REF(Type t) { assert t != null && !t.IsArray(); } - public case ARRAY(MSILType t) { assert t != null; } - - private final static CLRTypes pp = CLRTypes.instance(); - - public static final MSILType OBJECT = REF(pp.OBJECT); - public static final MSILType STRING = REF(pp.STRING); - public static final MSILType UNIT = REF(pp.getType("scala.Unit")); - - //########################################################################## - // factory methods - -// public static MSILType fromKind(int kind) { -// switch (kind) { -// case TypeTags.BYTE: return I1; -// case TypeTags.CHAR: return CHAR; -// case TypeTags.SHORT: return I2; -// case TypeTags.INT: return I4; -// case TypeTags.LONG: return I8; -// case TypeTags.FLOAT: return R4; -// case TypeTags.DOUBLE: return R8; -// case TypeTags.BOOLEAN: return BOOL; -// case TypeTags.UNIT: return VOID; -// case TypeTags.STRING: return STRING; -// default: -// throw Debug.abort("Unknown kind: " + kind); - -// } -// } - - public static MSILType fromType(Type type) { - if (type == pp.BYTE) return I1; - if (type == pp.SHORT) return I2; - if (type == pp.INT) return I4; - if (type == pp.LONG) return I8; - if (type == pp.FLOAT) return R4; - if (type == pp.DOUBLE) return R8; - if (type == pp.CHAR) return CHAR; - if (type == pp.VOID) return VOID; - if (type == pp.BOOLEAN)return BOOL; - if (type == pp.STRING) return STRING; - if (type == pp.OBJECT) return OBJECT; - if (type.IsArray()) - return ARRAY(fromType(type.GetElementType())); - return REF(type); - - } - - public static MSILType fromAConstant(AConstant value) { - switch (value) { - case UNIT: - return UNIT; // was VOID; // FIXME - case BOOLEAN(_): - return BOOL; - case BYTE(_): - return I1; - case SHORT(_): - return I2; - case CHAR(_): - return CHAR; - case INT(_): - return I4; - case LONG(_): - return I8; - case FLOAT(_): - return R4; - case DOUBLE(_): - return R8; - case STRING(_): - return STRING; - case NULL: - return NULL; - case ZERO: - return I4; - default: - throw Debug.abort("unknown case", value); - } - } - - public Type toType() { - switch (this) { - case I1: return pp.BYTE; - case I2: return pp.SHORT; - //case U2: return ; - case I4: return pp.INT; - case I8: return pp.LONG; - case R4: return pp.FLOAT; - case R8: return pp.DOUBLE; - case BOOL: return pp.BOOLEAN; - case CHAR: return pp.CHAR; - case REF(Type t): return t; - case ARRAY(MSILType t): return pp.mkArrayType(t.toType()); - case VOID: return pp.VOID; - //case NULL: return "NULL"; - default: throw Debug.abort(getClass().toString()); - } - - } - - //########################################################################## - - public boolean equals(Object that) { - if (this == that) - return true; - if (that == null || !(that instanceof MSILType)) - return false; - MSILType thatType = (MSILType)that; - switch (this) { - case REF(Type t1): - switch (thatType) { - case REF(Type t2): - return t1.equals(t2); - default: - return false; - } - case ARRAY(MSILType t1): - switch (thatType) { - case ARRAY(MSILType t2): - return t1.equals(t2); - default: - return false; - } - default: - return false; - } - } - - public boolean isReferenceType() { - switch (this) { - case REF(Type t): - return !t.IsValueType(); - case NULL: - case ARRAY(_): - return true; - default: - return false; - } - } - - public boolean isValueType() { - return !isReferenceType(); - } - - public boolean isEnum() { - switch (this) { - case REF(Type t): - return t.IsEnum(); - default: - return false; - } - } - - /** Returns the underlying type of an enumeration; null otherwise */ - public Type getUnderlyingType() { - switch (this) { - case REF(Type t): - return t.getUnderlyingType(); - default: - return null; - } -} - - public boolean isType(Type type) { - return equals(fromType(type)); - } - - public MSILType asPrimitive() { - switch (this) { - case REF(Type t): - if (t.IsEnum()) return fromType(t.getUnderlyingType()); - else return this; - //case NULL: - case ARRAY(_): - throw Debug.abort(this); - default: return this; - } - } - - /** Is this type is a subtype of that. */ - public boolean isSubtypeOf(MSILType that) { - assert that != null; - if (this == that - || (this.isReferenceType() && that.isType(pp.OBJECT))) - return true; - if (this.isValueType() && that.isReferenceType()) - return false; - switch (this) { - case BOOL: return that == I4; - case REF(Type t1): - switch (that) { - case REF(Type t2): - return t1.isSubtypeOf(t2); - default: - return false; - } - case ARRAY(MSILType t1): - switch (that) { - case ARRAY(MSILType t2): - return t1.isSubtypeOf(t2); - default: - return false; - } - case NULL: - switch (that) { - case REF(_): - case ARRAY(_): - return true; - default: - return false; - } - default: - return false; - } - } - - - private static final MSILType [] ARITHM_PRECISION = - new MSILType[] {I1, I2, CHAR, I4, I8, R4, R8}; - - /** - * @param t1 - * @param t2 - * @return the arithmetic coercion type for types t1 and t2 - */ - public static MSILType arithmCoercion(MSILType t1, MSILType t2) { - if (t1 == t2) return t1; - int i, j, n = ARITHM_PRECISION.length; - for (i = 0; i < n; i++) - if (t1 == ARITHM_PRECISION[i]) - break; - for (j = 0; j < n; j++) - if (t2 == ARITHM_PRECISION[j]) - break; - int m = Math.max(i, j); - if (m < n) - return ARITHM_PRECISION[m]; - else if (t1.isSubtypeOf(t2)) return t2; - else if (t2.isSubtypeOf(t1)) return t1; - else throw Debug.abort("cannot find coercion " + t1 + " => " + t2); - } - - public String toString() { - switch (this) { - case I1: return "I1"; - case I2: return "I2"; - case U2: return "U2"; - case I4: return "I4"; - case I8: return "I8"; - case R4: return "R4"; - case R8: return "R8"; - case BOOL: return "BOOL"; - case CHAR: return "CHAR"; - case REF(Type t): return "REF(" + t + ")"; - case ARRAY(MSILType t): return "ARRAY(" + t + ")"; - case VOID: return "VOID"; - case NULL: return "NULL"; - default: return getClass().getName(); - } - } - - //########################################################################## -} - - -/** - * The items used for deferred code generation. - */ -class Item { - public MSILType type; - - public case VoidItem(); - public case StackItem(); - public case SelfItem(); - public case LiteralItem(AConstant value); - public case ArgItem(int slot); - public case LocalItem(LocalBuilder local); - public case StaticItem(FieldInfo field); - public case SelectItem(Item qual, FieldInfo field); - public case CondItem(Test test, Chain success, Chain failure); - - public String toString() { - switch (this) { - case VoidItem(): return "VoidItem: " + type; - case StackItem(): return "StackItem: " + type ; - case SelfItem(): return "this: " + type; - case LiteralItem(AConstant value): - return "LiteralItem(" + value + "): " + type; - case ArgItem( int slot): - return "ArgItem(" + slot + "): " + type; - case LocalItem( LocalBuilder local): - return "LocalItem(" + local + "): " + type; - case StaticItem( FieldInfo field): - return "StaticItem(" + field + "): " + type; - case SelectItem(_, FieldInfo field): - return "SelectItem(" + field + "): " +type; - case CondItem(Test test, Chain success, Chain failure): - return "CondItem(" + test + ", " + success - + ", " + failure + "): " + type; - } - return "??Item??"; - } -} - - -/** - * Class implementing a chain (list) of labels. - */ -class Chain { - Label label; - Chain next; - Chain(Label l, Chain n) { label = l; next = n; } -} - - -/** - * Factory class for items. - */ -class ItemFactory { - GenMSIL coder; - private static final Item.VoidItem VOID = Item.VoidItem(); - static { VOID.type = MSILType.VOID; } - - public ItemFactory(GenMSIL _coder) { - coder = _coder; - } - public Item.VoidItem VoidItem() { - return VOID; - } - public Item.StackItem StackItem(MSILType type) { - Item.StackItem item = Item.StackItem(); - item.type = type; - assert item.type != null; - return item; - } - public Item.SelfItem SelfItem(Type t) { - Item.SelfItem item = Item.SelfItem(); - item.type = coder.msilType(t); - assert item.type != null; - return item; - } - public Item.LiteralItem LiteralItem(AConstant value) { - Item.LiteralItem item = Item.LiteralItem(value); - item.type = MSILType.fromAConstant(value); - assert item.type != null; - return item; - } - public Item.ArgItem ArgItem(MSILType type, int slot) { - Item.ArgItem item = Item.ArgItem(slot); - item.type = type; - assert item.type != null; - return item; - } - public Item.LocalItem LocalItem(LocalBuilder local) { - Item.LocalItem item = Item.LocalItem(local); - item.type = coder.msilType(local.LocalType); - assert item.type != null; - return item; - } - public Item.StaticItem StaticItem(FieldInfo field) { - assert field.IsStatic(); - Item.StaticItem item = Item.StaticItem(field); - item.type = coder.msilType(field.FieldType); - assert item.type != null; - return item; - } - public Item.SelectItem SelectItem(Item qualifier, FieldInfo field) { - assert !field.IsStatic(); - Item.SelectItem item = Item.SelectItem(qualifier, field); - item.type = coder.msilType(field.FieldType); - assert item.type != null; - return item; - } - public Item.CondItem CondItem(Test test, Chain success, Chain failure) { - Item.CondItem item = Item.CondItem(test, success, failure); - item.type = MSILType.BOOL; - return item; - } -} - -/** - * Class representing the possible tests in conditional item - */ -class Test { - - public case False; - public case True; - public case Bool(boolean value); - public case Or(Test test); - public case And(Test test); - public case Binary(int opcode, MSILType type); - - public static final int LT_IS = 0x00; - public static final int LE_IS = 0x01; - public static final int GT_IS = 0x02; - public static final int GE_IS = 0x03; - - public static final int LT_IU = 0x04; - public static final int LE_IU = 0x05; - public static final int GT_IU = 0x06; - public static final int GE_IU = 0x07; - - public static final int LT_RO = 0x08; - public static final int LE_RO = 0x09; - public static final int GT_RO = 0x0A; - public static final int GE_RO = 0x0B; - - public static final int LT_RU = 0x0C; - public static final int LE_RU = 0x0D; - public static final int GT_RU = 0x0E; - public static final int GE_RU = 0x0F; - - public static final int EQ = 0x10; - public static final int NE = 0x11; - - public static String toString(int opcode) { - switch (opcode) { - case LT_IS: return "GE_IS"; - case LE_IS: return "GT_IS"; - case GT_IS: return "LE_IS"; - case GE_IS: return "LT_IS"; - case LT_IU: return "GE_IU"; - case LE_IU: return "GT_IU"; - case GT_IU: return "LE_IU"; - case GE_IU: return "LT_IU"; - case LT_RO: return "GE_RU"; - case LE_RO: return "GT_RU"; - case GT_RO: return "LE_RU"; - case GE_RO: return "LT_RU"; - case LT_RU: return "GE_RO"; - case LE_RU: return "GT_RO"; - case GT_RU: return "LE_RO"; - case GE_RU: return "LT_RO"; - case EQ : return "NE"; - case NE : return "EQ"; - default : throw Debug.abort("" + opcode); - } - } - - public String toString() { - switch (this) { - - case False: - return "False"; - case True: - return "True"; - case Bool(boolean value): - return "Test(" + value + ")"; - case Or(Test test): - return "Or(" + test + ")"; - case And(Test test): - return "And(" + test + ")"; - case Binary(int opcode, MSILType type): - return "Binary(" + toString(opcode) +"," + type + ")"; - - default: - throw Debug.abort(getClass().getName()); - } - } -} // class Test diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java deleted file mode 100644 index de0bd4a264..0000000000 --- a/sources/scalac/backend/msil/TypeCreator.java +++ /dev/null @@ -1,1449 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.backend.msil; - -import scalac.Global; -import scalac.Phase; -import scalac.CompilationUnit; -import scalac.ApplicationError; -import scalac.ast.Tree; -import scalac.ast.Traverser; -import scalac.atree.AConstant; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.SourceRepresentation; -import scalac.symtab.Kinds; -import scalac.symtab.TypeTags; -import scalac.symtab.Symbol; -import scalac.symtab.Scope; -import scalac.symtab.Modifiers; -import scalac.symtab.Definitions; -import scalac.symtab.AttributeInfo; -import scalac.symtab.classfile.CLRTypes; -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -import Tree.*; - -import ch.epfl.lamp.compiler.msil.*; -import ch.epfl.lamp.compiler.msil.emit.*; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; -import java.util.Map; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Set; -import java.util.HashSet; -import java.util.LinkedHashSet; - -/** - * Creates System.Reflection objects corresponding to - * Scala symbols - * - * @author Nikolay Mihaylov - * @version 1.1 - */ - -final class TypeCreator { - - //private final GenMSIL gen; - private final Global global; - private final Definitions defs; - - private final ArrayList typeBuilders = new ArrayList(); - - // for every method of an object give the corresponding static method - // of the accompanying class - private final Map/*<Symbol, MethodBuilder>*/ syms2staticMethods = new HashMap(); - - private final Map types2symbols = new HashMap(); - private final Map symbols2types = new HashMap(); - private final Map symbols2fields = new HashMap(); - private final Map symbols2methods = new HashMap(); - private final Map symbols2moduleFields = new HashMap(); - private final Set specialAttrs = new HashSet(); - - public static final String MODULE_S = "$MODULE"; - - public final Type BYTE; - public final Type CHAR; - public final Type SHORT; - public final Type INT; - public final Type LONG; - public final Type FLOAT; - public final Type DOUBLE; - public final Type BOOLEAN; - public final Type VOID; - public final Type ENUM; - - public final Type OBJECT; - public final Type STRING; - public final Type STRING_ARRAY; - public final Type ICLONEABLE; - - private final Type MONITOR; - - public final MethodInfo CONCAT_OBJECT_OBJECT; - public final MethodInfo OBJECT_EQUALS; - public final MethodInfo MONITOR_ENTER; - public final MethodInfo MONITOR_EXIT; - public final MethodInfo MEMBERWISE_CLONE; -// private final MethodInfo MONITOR_PULSE; -// private final MethodInfo MONITOR_PULSE_ALL; -// private final MethodInfo MONITOR_WAIT; -// private final MethodInfo MONITOR_WAIT_TIMEOUT; - - public final Type SCALA_BYTE; - public final Type SCALA_SHORT; - public final Type SCALA_INT; - public final Type SCALA_LONG; - public final Type SCALA_FLOAT; - public final Type SCALA_DOUBLE; - public final Type SCALA_CHAR; - public final Type SCALA_BOOLEAN; - public final Type SCALA_UNIT; - - public final MethodInfo RUNTIME_BOX_UNIT ; - - public Symbol SYM_SUBSTRING_INT_INT; - public MethodInfo SUBSTRING_INT_INT; - public Symbol SYM_COMPARE_TO_IGNORE_CASE; - public MethodInfo COMPARE_TO_IGNORE_CASE; - - public ConstructorInfo SYMTAB_CONSTR; - public ConstructorInfo SYMTAB_DEFAULT_CONSTR; - - private scalac.symtab.Type MAIN_METHOD_TYPE; - - private final Symbol SYSTEM_SERIALIZABLE_CONSTR; - private final Symbol SYSTEM_NONSERIALIZED_CONSTR; - - private final CLRTypes ti; - - private final Phase backPhase; - - //########################################################################## - - TypeCreator(Global global) { - this.global = global; - this.defs = global.definitions; - this.backPhase = global.PHASE.ADDINTERFACES.phase(); - - ti = CLRTypes.instance(); - - BYTE = ti.BYTE; - CHAR = ti.CHAR; - SHORT = ti.SHORT; - INT = ti.INT; - LONG = ti.LONG; - FLOAT = ti.FLOAT; - DOUBLE = ti.DOUBLE; - BOOLEAN = ti.BOOLEAN; - VOID = ti.VOID; - ENUM = ti.ENUM; - - OBJECT = ti.OBJECT; - STRING = ti.STRING; - STRING_ARRAY = Type.GetType("System.String[]"); - ICLONEABLE = Type.GetType("System.ICloneable"); - MONITOR = Type.GetType("System.Threading.Monitor"); - - final Type[] sObject1 = new Type[] {OBJECT}; - - //CONCAT_OBJECT = STRING.GetMethod("Concat", new Type[] {OBJECT}); - //CONCAT_STRING_STRING = STRING.GetMethod("Concat", new Type[] {STRING, STRING}); - CONCAT_OBJECT_OBJECT = - STRING.GetMethod("Concat", new Type[] {OBJECT, OBJECT}); - OBJECT_EQUALS = OBJECT.GetMethod("Equals", sObject1); -// MONITOR_PULSE = MONITOR.GetMethod("Pulse", sObject1); -// MONITOR_PULSE_ALL = MONITOR.GetMethod("PulseAll", sObject1); -// MONITOR_WAIT = MONITOR.GetMethod("Wait", sObject1); -// MONITOR_WAIT_TIMEOUT = MONITOR.GetMethod("Wait", new Type[] {OBJECT, INT}); - MONITOR_ENTER = MONITOR.GetMethod("Enter", sObject1); - MONITOR_EXIT = MONITOR.GetMethod("Exit", sObject1); - MEMBERWISE_CLONE = ti.MEMBERWISE_CLONE; - - SCALA_BYTE = getType("scala.Byte"); - SCALA_SHORT = getType("scala.Short"); - SCALA_INT = getType("scala.Int"); - SCALA_LONG = getType("scala.Long"); - SCALA_FLOAT = getType("scala.Float"); - SCALA_DOUBLE = getType("scala.Double"); - SCALA_CHAR = getType("scala.Char"); - SCALA_BOOLEAN = getType("scala.Boolean"); - SCALA_UNIT = getType("scala.Unit"); - - RUNTIME_BOX_UNIT = getType("scala.runtime.RunTime") - .GetMethod("box_uvalue", Type.EmptyTypes); - ti.map(defs.OBJECT_CLONE, MEMBERWISE_CLONE); - - SYSTEM_SERIALIZABLE_CONSTR = defs.getClass("System.SerializableAttribute") - .primaryConstructor(); - SYSTEM_NONSERIALIZED_CONSTR = defs.getClass("System.NonSerializedAttribute") - .primaryConstructor(); - - } - - private boolean initialized = false; - - /* - * Called from GenMSILPhase - */ - public void init() { - if (initialized) - return; - final Symbol JOBJECT = defs.OBJECT_CLASS; //defs.getClass("java.lang.Object"); - final Symbol JSTRING = defs.STRING_CLASS; - - // initialize type mappings - map(defs.ANY_CLASS, OBJECT); - map(defs.ANYREF_CLASS, OBJECT); - map(JOBJECT, OBJECT); - map(JSTRING, STRING); - - // constants useful for method mappings - final scalac.symtab.Type UNBOXED_LONG = - new scalac.symtab.Type.UnboxedType(TypeTags.LONG); - final scalac.symtab.Type UNBOXED_INT = - new scalac.symtab.Type.UnboxedType(TypeTags.INT); - final scalac.symtab.Type UNBOXED_CHAR = - new scalac.symtab.Type.UnboxedType(TypeTags.CHAR); - - final scalac.symtab.Type[] jEmpty = scalac.symtab.Type.EMPTY_ARRAY; - final scalac.symtab.Type[] jString1 = new scalac.symtab.Type[] - {defs.STRING_TYPE()}; - final scalac.symtab.Type[] jInt1 = new scalac.symtab.Type[] - {UNBOXED_INT}; - final scalac.symtab.Type[] jInt2 = new scalac.symtab.Type[] - {UNBOXED_INT, UNBOXED_INT}; - final scalac.symtab.Type[] jStringInt = new scalac.symtab.Type[] - {defs.STRING_TYPE(), UNBOXED_INT}; - final scalac.symtab.Type[] jChar2 = new scalac.symtab.Type[] - {UNBOXED_CHAR, UNBOXED_CHAR}; - - final Type[] sObject1 = new Type[] {OBJECT}; - final Type[] sString1 = new Type[] {STRING}; - final Type[] sString2 = new Type[] {STRING, STRING}; - final Type[] sChar1 = new Type[] {CHAR}; - final Type[] sCharInt2 = new Type[] {CHAR, INT}; - - final Type ObjectImpl = Type.GetType("com.ms.vjsharp.lang.ObjectImpl"); - - // map methods of java.lang.Object - translateMethod(JOBJECT, "equals", OBJECT, "Equals"); - translateMethod(JOBJECT, "hashCode", OBJECT, "GetHashCode"); - translateMethod(JOBJECT, "toString", OBJECT, "ToString"); - translateMethod(JOBJECT, "finalize", OBJECT, "Finalize"); - translateMethod(JOBJECT, "wait", jEmpty, MONITOR, "Wait", sObject1); - translateMethod(JOBJECT, "wait", new scalac.symtab. - Type[] {UNBOXED_LONG}, // defs.LONG_TYPE - MONITOR, "Wait", - new Type[] {OBJECT, INT}); - translateMethod(JOBJECT, "notify", jEmpty, MONITOR, "Pulse", sObject1); - translateMethod(JOBJECT, "notifyAll", jEmpty, MONITOR, "PulseAll", sObject1); - //translateMethod(JOBJECT, "getClass", jEmpty, ObjectImpl, "getClass", sObject1); - - // map methods of java.lang.String - //translateMethod(JSTRING, "equals", STRING, "Equals"); - //translateMethod(JSTRING, "toString", STRING, "ToString"); - translateMethod(JSTRING, "compareTo", STRING, "CompareTo"); - translateMethod(JSTRING, "length", STRING, "get_Length"); - translateMethod(JSTRING, "charAt", STRING, "get_Chars"); - translateMethod(JSTRING, "concat", jString1, STRING, "Concat", sString2); - translateMethod(JSTRING, "indexOf", jInt1, STRING, "IndexOf", sChar1); - translateMethod(JSTRING, "indexOf", jInt2, STRING, "IndexOf", sCharInt2); - translateMethod(JSTRING, "indexOf", jString1, STRING, "IndexOf"); - translateMethod(JSTRING, "indexOf", jStringInt, STRING, "IndexOf"); - translateMethod(JSTRING, "lastIndexOf", jInt1, STRING, "LastIndexOf", sChar1); - translateMethod(JSTRING, "lastIndexOf", jInt2, STRING, "LastIndexOf", sCharInt2); - translateMethod(JSTRING, "lastIndexOf", jString1, STRING, "LastIndexOf"); - translateMethod(JSTRING, "lastIndexOf", jStringInt, STRING, "LastIndexOf"); - translateMethod(JSTRING, "toLowerCase", jEmpty, STRING, "ToLower"); - translateMethod(JSTRING, "toUpperCase", jEmpty, STRING, "ToUpper"); - translateMethod(JSTRING, "startsWith", jString1, STRING, "StartsWith"); - translateMethod(JSTRING, "endsWith", jString1, STRING, "EndsWith"); - translateMethod(JSTRING, "substring", jInt1, STRING, "Substring"); - translateMethod(JSTRING, "intern", jEmpty, STRING, "Intern", sString1); - translateMethod(JSTRING, "replace", jChar2, STRING, "Replace"); - translateMethod(JSTRING, "toCharArray", STRING, "ToCharArray"); - -// translateMethod(defs.getModule("java.lang.Byte").moduleClass() -// , "parseByte", jString1, BYTE, "Parse"); -// translateMethod(defs.getModule("java.lang.Short").moduleClass() -// , "parseShort", jString1, SHORT, "Parse"); -// translateMethod(defs.getModule("java.lang.Integer").moduleClass() -// , "parseInt", jString1, INT, "Parse"); -// translateMethod(defs.getModule("java.lang.Long").moduleClass() -// , "parseLong", jString1, LONG, "Parse"); -// translateMethod(defs.getModule("java.lang.Float").moduleClass() -// , "parseFloat", jString1, FLOAT, "Parse"); -// translateMethod(defs.getModule("java.lang.Double").moduleClass() -// , "parseDouble", jString1, DOUBLE, "Parse"); - - SYM_SUBSTRING_INT_INT = lookupMethod(JSTRING, "substring", jInt2); - SUBSTRING_INT_INT = - STRING.GetMethod("Substring", new Type[]{INT,INT}); - SYM_COMPARE_TO_IGNORE_CASE = - lookupMethod(JSTRING, "compareToIgnoreCase", jString1); - COMPARE_TO_IGNORE_CASE = - STRING.GetMethod("Compare", new Type[]{STRING, STRING, BOOLEAN}); - initialized = true; - - SYMTAB_CONSTR = ti.SYMTAB_CONSTR; - SYMTAB_DEFAULT_CONSTR = ti.SYMTAB_DEFAULT_CONSTR; - - scalac.symtab.Type argument = defs.array_TYPE(defs.STRING_TYPE()); - scalac.symtab.Type result = defs.void_TYPE(); - Symbol formal = Symbol.NONE.newTerm // !!! should be newVParam - (Position.NOPOS, Modifiers.PARAM, Name.fromString("args")); - formal.setInfo(argument); - MAIN_METHOD_TYPE = - scalac.symtab.Type.MethodType(new Symbol[] {formal}, result); - - specialAttrs.add(defs.SCALA_SERIALIZABLE_CONSTR); - specialAttrs.add(defs.SCALA_TRANSIENT_CONSTR); - specialAttrs.add(SYSTEM_SERIALIZABLE_CONSTR); - specialAttrs.add(SYSTEM_NONSERIALIZED_CONSTR); - specialAttrs.add(defs.SCALA_CLONEABLE_CONSTR); - specialAttrs.add(defs.SCALA_VOLATILE_CONSTR); - specialAttrs.add(defs.getClass("scala.SerialVersionUID") - .primaryConstructor()); - specialAttrs.add(defs.getClass("scala._trait_") - .primaryConstructor()); - } // init() - - /* - * Looks up the method with the corresponding signature - */ - private Symbol lookupMethod(Symbol clazz, String name, - scalac.symtab.Type[] paramTypes) - { - Symbol[] methods = clazz.members(). - lookup(Name.fromString(name)).alternativeSymbols(); - search: - for (int i = 0; i < methods.length; i++) { - switch (methods[i].info()) { - case MethodType(Symbol[] vparams, _): - if (paramTypes.length != vparams.length) - continue; - for (int j = 0; j < vparams.length; j++) { - if (!paramTypes[j].isSameAs(vparams[j].info())) - continue search; - } - return methods[i]; - default: - continue; - } - } - return null; - } // Symbol lookupMethod(...) - - /* - * Format the signature of a method for better diagnostic printing. - */ - private static String methodSignature(Symbol sym) { - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - StringBuffer s = new StringBuffer(); - s.append(result); s.append(' '); - s.append(Debug.show(sym.owner())); s.append('.'); - s.append(sym.name.toString());s.append('('); - for (int i = 0; i < vparams.length; i++) { - if (i > 0) s.append(", "); - //s.append(Debug.show(vparams[i].info())); - s.append(vparams[i].info()); - } - s.append(")"); - return s.toString(); - default: - return "Symbol doesn't have a method type: " + Debug.show(sym); - } - } - - private static String methodSignature(Type[] params) { - StringBuffer s = new StringBuffer(); - s.append('('); - for (int i = 0; i < params.length; i++) { - if (i > 0) - s.append(", "); - s.append(params[i]); - } - s.append(')'); - return s.toString(); - } - - /** - * Create a mapping from method with symbol 'sym' - * to the method newClazz.newName(params) - */ - private void mapMethod(Symbol sym, Type newClazz, String name, Type[] params) { - MethodInfo method = newClazz.GetMethod(name, params); - assert method != null : "Cannot find translation for: " - + methodSignature(sym) + "->" + newClazz - + "::" + name + methodSignature(params); - symbols2methods.put(sym, method); - } - - /** - * Create mapping between the specified two methods only - */ - private void translateMethod(Symbol clazz, String name, - scalac.symtab.Type[] paramTypes, - Type newClazz, String newName, Type[] newParamTypes) - { - Symbol sym = lookupMethod(clazz, name, paramTypes); - assert sym != null : "Cannot find method: " + name + " in class " + - Debug.show(clazz) + "; scope = " + Debug.show(clazz.members()); - mapMethod(sym, newClazz, newName, newParamTypes); - } - - /** - * Lookup the method and create mapping for all overloaded alternatives - * to the corresponding methods in 'newClazz' - */ - private void translateMethod(Symbol clazz, String name, - Type newClazz, String newName) - { - Symbol sym = clazz.lookup(Name.fromString(name)); - assert sym != null : "Cannot find method: " + name; - translateMethod(sym, newClazz, newName); - } - - /** - * - */ - private void translateMethod(Symbol clazz, String name, - scalac.symtab.Type[] paramTypes, - Type newClazz, String newName) - { - Type[] newParamTypes = new Type[paramTypes.length]; - for (int i = 0; i < paramTypes.length; i++) - newParamTypes[i] = getType(paramTypes[i]); - translateMethod(clazz, name, paramTypes, - newClazz, newName, newParamTypes); - } - - /* - * Create a mapping for the two methods. - */ - private void translateMethod(Symbol sym, Type newClazz, String newName) { - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - Type[] params = new Type[vparams.length]; - for (int i = 0; i < params.length; i++) - params[i] = getType(vparams[i]); - mapMethod(sym, newClazz, newName, params); - break; - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - translateMethod(alts[i], newClazz, newName); - return; - default: - throw Debug.abort(Debug.show(sym, sym.info())); - } - } - - //########################################################################## - // tree treversal - - private static final Name MAIN_N = Name.fromString("main"); - - private final Set types2create = new LinkedHashSet(); - - private String assemName; - - private File outDir; - - private Symbol entryPoint; - - private boolean moreThanOneEntryPoint; - public boolean moreThanOneEntryPoint() { - return moreThanOneEntryPoint; - } - - private CompilationUnit entryPointUnit; - - private int entryPointPos; - - /** - collects the symbols of all classes defined in the program - * - collects all entry points - * - gives the name of the new assembly - */ - public void collectSymbols(CompilationUnit[] units) { - types2create.clear(); - entryPoint = null; - new CollectSymbols().traverse(units); - - // the assembly name supplied with the -o option (or null) - assemName = global.args.assemname.value; - - if (assemName == null) { - // assembly name not supplied with the -o option - if (entryPoint != null) { - // assume the name of the object defining the first entry point - assemName = entryPoint.owner().name.toString(); - } else { - // assume the name of the first source file - assemName = entryPointUnit.source.getFile().getName(); - assert assemName.endsWith(".scala") : assemName; - assemName = assemName.substring(0, assemName.length() - 6); - } - } else { - File f = new File(assemName); - outDir = f.getParentFile(); - assemName = f.getName(); - } - if (outDir == null) - outDir = new File("."); - } - - /** Determines if the given symbol is an entry point: - * - the name is "main" - * - belongs to a top-level class - * - the type is Array[String] => Unit - */ - public boolean isEntryPoint(Symbol main) { - return main.name == MAIN_N - && main.owner().isModuleClass() - && main.owner().owner().isPackageClass() - && MAIN_METHOD_TYPE.isSameAs(main.info()); - } - - /** A traverser that collects the symbols of all classes defined - * in the program and all entry points. - */ - private final class CollectSymbols extends Traverser { - private CompilationUnit currUnit; - public void traverse(CompilationUnit unit) { - currUnit = unit; - if (entryPointUnit == null) - entryPointUnit = unit; - super.traverse(unit); - } - public void traverse(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, Template impl): - types2create.add(tree.symbol()); - traverse(impl); - return; - case DefDef(_, _, _, _, _, _): - Symbol sym = tree.symbol(); - if (isEntryPoint(sym)) { - if (entryPoint == null) { - entryPoint = sym; - entryPointUnit = currUnit; - entryPointPos = tree.pos; - } else - moreThanOneEntryPoint = true; - } - return; - case ValDef(_, _, _, _): - return; - default: - super.traverse(tree); - } - } - } - - //########################################################################## - - // the Assembly the program is compiled into. - private AssemblyBuilder msilAssembly; - - // the main module of the assembly - private ModuleBuilder msilModule; - - /** Create the output assembly - */ - void initAssembly() { - AssemblyName an = new AssemblyName(); - an.Name = assemName; - String moduleName = assemName + (entryPoint == null ? ".dll" : ".exe"); - msilAssembly = AssemblyBuilder.DefineDynamicAssembly(an); - msilModule = msilAssembly.DefineDynamicModule - (moduleName, new File(outDir, moduleName).getAbsolutePath()); - - for (Iterator classes = types2create.iterator(); classes.hasNext();) { - Symbol clazz = (Symbol)classes.next(); - createType(clazz); - } - } - - /** Finilize the code generation. Called from GenMSILPhase - * after processing all compilation units. - */ - public void saveAssembly() { - if (entryPoint != null) { - MethodInfo mainMethod = (MethodInfo)getMethod(entryPoint); - assert mainMethod != null : Debug.show(entryPoint); - FieldInfo moduleField = getModuleField(entryPoint.owner()); - assert moduleField != null : Debug.show(entryPoint.owner()); - MethodBuilder main = msilModule.DefineGlobalMethod - ("Main", MethodAttributes.Public | MethodAttributes.Static, - VOID, new Type[] {STRING_ARRAY} ); - main.DefineParameter(0, 0, "args"); - msilAssembly.SetEntryPoint(main); - ILGenerator code = main.GetILGenerator(); - if (global.args.debuginfo.value) { - String fname = SourceRepresentation - .escape(entryPointUnit.source.getFile().getPath()); - code.setPosition(Position.line(entryPointPos), fname); - } - - code.Emit(OpCodes.Ldsfld, moduleField); - code.Emit(OpCodes.Ldarg_0); - code.Emit(OpCodes.Callvirt, mainMethod); - code.Emit(OpCodes.Ret); - } - createTypes(); - File fassem = new File(outDir, assemName + ".il"); - String assemblyFilename = fassem.getPath(); - try { - msilAssembly.Save(assemblyFilename); - if (moreThanOneEntryPoint()) - global.warning("Setting " + Debug.show(entryPoint) + - " as an entry point"); - } catch (IOException e) { - global.error("Could not save " + assemblyFilename); - } - } - - /** - * Finalizes ('bakes') the newly created types - */ - private void createTypes() { - Iterator iter = typeBuilders.iterator(); - while (iter.hasNext()) - ((TypeBuilder)iter.next()).CreateType(); - } - - //########################################################################## - /** - * Creates bidirectional mapping from symbols to types. - */ - private Type map(Symbol sym, Type type) { - symbols2types.put(sym, type); - if (sym.isClass()) - types2symbols.put(type, sym); - return type; - } - - /** - * Return the System.Type object with the given name. - */ - private Type getType(String name) { - return ti.getType(name); - } - - /** - * Return the System.Type object corresponding to the type of the symbol - */ - public Type getType(Symbol sym) { - if (sym == null) return null; // FIXME: assert sym != null ? - if (sym == defs.ANY_CLASS || sym == defs.ANYREF_CLASS || sym == defs.OBJECT_CLASS) - return OBJECT; - if (sym == defs.STRING_CLASS) - return STRING; - - Type type = (Type) symbols2types.get(sym); - if (type != null) { - if (sym.isExternal()) { - assert !(type instanceof TypeBuilder) - : Debug.show(sym) + " -> " + type.toString(); - return type; - } else if (types2create.contains(sym) && type instanceof TypeBuilder) - return type; - } else if (types2create.contains(sym)) - type = createType(sym); - if (type != null) - return type; - - type = (Type)ti.getMember(sym); - if (type != null) - return map(sym, type); - - if (sym.isClass()) { - final Symbol owner = sym.owner(); - if (owner.isClass()) { - Type ownerType = getType(owner); - assert ownerType != null : Debug.show(owner); - type = ownerType.GetNestedType(sym.name.toString()); - } else { - String name = global.primitives.getCLRClassName(sym); - type = getType(sym.isModuleClass() && !sym.isJava() - ? name + "$" : name); - } - } else { - type = getType(sym.info()); - } - if (type != null) - return map(sym, type); - - throw Debug.abort("Type resolution failed for " + Debug.show(sym)); - } - - /** Retrieve the System.Type from the scala type. - */ - public Type getType(scalac.symtab.Type type) { - switch (type) { - case ThisType(Symbol s): - return getType(s); - case TypeRef(_, Symbol s, _): - return getType(s); - case CompoundType(_, _): - return getType(type.symbol()); - case UnboxedType(int kind): - return getTypeFromKind(kind); - case UnboxedArrayType(scalac.symtab.Type elemtp): - return ti.mkArrayType(getType(elemtp)); - case NoType: - return VOID; - default: - throw Debug.abort(Debug.show(type)); - } - } - - /** Retrieves the primitive datatypes given their kind - */ - private Type getTypeFromKind(int kind) { - switch (kind) { - case TypeTags.CHAR: return CHAR; - case TypeTags.BYTE: return BYTE; - case TypeTags.SHORT: return SHORT; - case TypeTags.INT: return INT; - case TypeTags.LONG: return LONG; - case TypeTags.FLOAT: return FLOAT; - case TypeTags.DOUBLE: return DOUBLE; - case TypeTags.BOOLEAN: return BOOLEAN; - case TypeTags.UNIT: return VOID; - case TypeTags.STRING: return STRING; - default: - throw new ApplicationError("Unknown kind: " + kind); - } - } - - public Symbol getSymbol(Type type) { - return (Symbol) types2symbols.get(type); - } - - public Type createType(Symbol clazz) { - try { return createType0(clazz); } - catch (Error e) { - throw Debug.abort(Debug.show(clazz), e); - } - } - - /** - * Creates the TypeBuilder for a class. - */ - public Type createType0(Symbol clazz) { - assert types2create.contains(clazz) : Debug.show(clazz); - Type type = (Type)symbols2types.get(clazz); - if (type != null && type instanceof TypeBuilder) - return type; - - TypeBuilder staticType = null; - final Symbol owner = clazz.owner(); - final String staticTypeName = owner.isClass() - ? clazz.nameString() - : global.primitives.getCLRClassName(clazz); - final String typeName = - staticTypeName + (clazz.isModuleClass() ? "$" : ""); - final scalac.symtab.Type classType = clazz.info(); - switch (classType) { - case CompoundType(scalac.symtab.Type[] baseTypes, _): - Type superType = null; - Type[] interfaces = null; - int inum = baseTypes.length; - if (clazz.isInterface()) { - int baseIndex = 0; - if (baseTypes[0].symbol() == defs.ANY_CLASS) { - --inum; - baseIndex = 1; - } - interfaces = new Type[inum]; - for (int i = 0; i < inum; i++) { - assert baseTypes[i + baseIndex].symbol().isInterface(); - interfaces[i] = getType(baseTypes[i + baseIndex].symbol()); - } - } else { - boolean cloneable = isCloneable(clazz); - superType = getType(baseTypes[0].symbol()); - assert inum > 0; - interfaces = new Type[inum - 1 + (cloneable ? 1 : 0)]; - for (int i = 1; i < inum; i++) - interfaces[i - 1] = getType(baseTypes[i].symbol()); - if (cloneable) - interfaces[inum - 1] = ICLONEABLE; - } - - type = (TypeBuilder) symbols2types.get(clazz); - if (type != null) - return type; - - if (owner.isPackageClass()) { // i.e. top level class - type = msilModule.DefineType - (typeName, translateTypeAttributes(clazz, false), - superType, interfaces); - if (clazz.isModuleClass()) { - Symbol module = owner.members().lookup(clazz.name.toTermName()); - Symbol linkedClass = module.linkedClass(); - - if (linkedClass == null || linkedClass.info().isError()) { - staticType = msilModule.DefineType - (staticTypeName, - translateTypeAttributes(clazz, false), - OBJECT, Type.EmptyTypes); - } - } - } else { - final Type outerType = (Type) getType(owner); - // check if the type have not been created by - // the (possible) creation of the outer type - type = (TypeBuilder) symbols2types.get(clazz); - if (type != null) - return type; - - assert outerType instanceof TypeBuilder : Debug.show(clazz); - type = ((TypeBuilder)outerType).DefineNestedType - (typeName, translateTypeAttributes(clazz, true), - superType, interfaces); - } - break; - - default: - throw Debug.abort("Symbol does not have a CompoundType", clazz); - } - typeBuilders.add(type); - map(clazz, type); - if (clazz.isModuleClass() && staticType != null) { - syms2staticTypes.put(clazz, staticType); - } - for (Scope.SymbolIterator syms = clazz.members().iterator(); - syms.hasNext(); ) - { - Symbol member = syms.next(); - if (member.isMethod()) { - MethodBase m = createMethod(member); - if (staticType != null && m.IsPublic() && !m.IsConstructor()) { - MethodBase sm = createMethod(staticType, member, true); - syms2staticMethods.put(member, sm); - } - } - else if (!member.isClass() && !member.isModule() - && !member.isType()) - createField(member); - } - - // adapted from Erasure; creates abstract method declarations - // for the interface methods for which the class doesn't provide - // implementation (requirement of the CLR) - if (clazz.isClass() && !clazz.isInterface()) { - Set ifaces = new HashSet(getInterfacesOf(clazz)); - Symbol svper = clazz.parents()[0].symbol(); - ifaces.removeAll(getInterfacesOf(svper)); - for (Iterator i = ifaces.iterator(); i.hasNext(); ) { - Symbol iface = (Symbol)i.next(); - for (Scope.SymbolIterator members = - iface.members().iterator(); - members.hasNext(); ) - { - Symbol method = members.next(); - if (!method.isTerm() || !method.isDeferred()) continue; - Symbol overriding = - method.overridingSymbol(clazz.info(), true); - if (overriding != method) continue; - Symbol overridden = method - .overriddenSymbol(clazz.parents()[0], clazz, true); - if (overridden.isNone()) { - Symbol newMethod = method.cloneSymbol(clazz); - newMethod.flags = (newMethod.flags & ~Modifiers.JAVA) - | Modifiers.SYNTHETIC | Modifiers.DEFERRED; - createMethod(newMethod); - } - } - } - } - setAttributes((TypeBuilder)type, global.getAttributes(clazz)); - return type; - } // createType() - - private final Map interfaces/*<Symbol,Set<Symbol>>*/ = new HashMap(); - - /** Adapted from Erasure. Returns a set of the interfaces - * implemented by the class. - */ - private Set getInterfacesOf(Symbol clasz) { - assert clasz.isClass(): Debug.show(clasz); - Set set = (Set)interfaces.get(clasz); - if (set == null) { - set = new HashSet(); - interfaces.put(clasz, set); - scalac.symtab.Type parents[] = clasz.parents(); - for (int i = 0; i < parents.length; i++) - set.addAll(getInterfacesOf(parents[i].symbol())); - if (clasz.isInterface()) set.add(clasz); - } - return set; - } - - public boolean isCloneable(Symbol clazz) { - return global.getAttrArguments(clazz, defs.SCALA_CLONEABLE_CONSTR) - != null; - } - - //########################################################################## - // find/create methods - - public MethodBase getMethod(Symbol sym) { - MethodBase method = null; - try { - method = getMethod0(sym); - } catch (Throwable e) { - printMapping(sym, symbols2methods); - throw Debug.abort(Debug.show(sym), e); - } - return method; - } - - private static String dumpSymbol(Symbol sym) { - return Debug.show(sym) + " : " + Integer.toHexString(sym.flags); - } - private void printMapping(Symbol sym, Map map) { - System.out.println("For symbol " + dumpSymbol(sym)); - for (Iterator entries = map.entrySet().iterator(); - entries.hasNext(); ) - { - Map.Entry entry = (Map.Entry)entries.next(); - Symbol sentry = (Symbol)entry.getKey(); - if (sentry.owner() == sym.owner() - && sentry.name == sym.name) - { - System.out.println("Existing mapping " - + dumpSymbol(sentry) + " => " - + entry.getValue()); - } - } - System.out.println("Scope of owner: " + sym.owner().members()); - } - - /** - * Returns the MethodBase object corresponding to the symbol. - */ - public MethodBase getMethod0(Symbol sym) { - MethodBase method = (MethodBase) symbols2methods.get(sym); - if (method != null) - return method; - MemberInfo m = ti.getMember(sym); - if (m != null && m instanceof MethodBase) { - method = (MethodBase) m; - } else { - // force the creation of the declaring type - Type owner = getType(sym.owner()); - assert owner != null : Debug.show(sym); - method = (MethodBase) symbols2methods.get(sym); - if (method != null) - return method; - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - Type[] params = new Type[vparams.length]; - Type resType = getType(result); - for (int i = 0; i < params.length; i++) - params[i] = getType(vparams[i]); - if (sym.isInitializer()) { - // The owner of a constructor is the outer class - // so get the result type of the constructor - method = owner.GetConstructor(params); - assert method != null : "cannot find " + owner - + "::.ctor" + methodSignature(params); - } else { - method = owner instanceof TypeBuilder - ? findMethod(sym.owner(), sym) - : owner.GetMethod - (getMethodName(sym.name, params), params, resType); - } - break; - default: - throw Debug.abort("Symbol doesn't have a method type", sym); - } - assert method != null - : Debug.show(owner) + " => Cannot find method: " + methodSignature(sym); - } - symbols2methods.put(sym, method); - - return method; - } - - /** - * Returns all MethodBase objects corresponding to the symbol. - */ - private MethodBase[] getMethods(Symbol sym) { - MethodBase method = (MethodBase) symbols2methods.get(sym); - if (method != null) - return new MethodBase[]{method}; - MemberInfo m = ti.getMember(sym); - if (m != null && m instanceof MethodBase) { - method = (MethodBase) m; - } else { - // force the creation of the declaring type - Type owner = getType(sym.owner()); - assert owner != null : Debug.show(sym); - method = (MethodBase) symbols2methods.get(sym); - if (method != null) - return new MethodBase[]{method}; - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - Type[] params = new Type[vparams.length]; - Type resType = getType(result); - for (int i = 0; i < params.length; i++) - params[i] = getType(vparams[i]); - if (sym.isInitializer()) { - // The owner of a constructor is the outer class - // so get the result type of the constructor - method = owner.GetConstructor(params); - assert method != null : "cannot find " + owner - + "::.ctor" + methodSignature(params); - } else { - method = owner instanceof TypeBuilder - ? findMethod(sym.owner(), sym) - : owner.GetMethod - (getMethodName(sym.name, params), params, resType); - } - break; - case OverloadedType(Symbol[] alts, scalac.symtab.Type[] alttypes): - MethodBase[] methods = new MethodBase[alts.length]; - for (int i = 0; i < alts.length; i++) - methods[i] = getMethod(alts[i]); - return methods; - - default: - throw Debug.abort("Symbol doesn't have a method type", sym); - } - assert method != null - : Debug.show(owner) + " => Cannot find method: " + methodSignature(sym); - } - symbols2methods.put(sym, method); - return new MethodBase[]{method}; - } - - /** - * Returns the exactest apply method. - * The exactest method is taken to be the first method that doesn't have - * an 'object' return type and all 'object' parameter types. - */ - public MethodBase getDelegateApplyMethod(Symbol sym) { - MethodBase methods[] = getMethods(sym); - if(methods.length > 1) { - assert methods.length == 2; - for (int i = 0; i < methods.length; i++) { - if(((MethodInfo)methods[i]).ReturnType != OBJECT) - return methods[i]; - ParameterInfo pi[] = methods[i].GetParameters(); - for (int j = 0; j < pi.length; j++) { - if(pi[j].ParameterType != OBJECT) - return methods[i]; - } - } - throw Debug.abort("Expected apply method not found", sym); - } else { - return methods[0]; - } - } - - private String getMethodName(Name name, Type[] params) { - if (name == Names.finalize && params.length == 0) - return "Finalize"; - if (name == Names.toString && params.length == 0) - return "ToString"; - if (name == Names.hashCode && params.length == 0) - return "GetHashCode"; - if (name == Names.equals && params.length == 1 && params[0] == OBJECT) - return "Equals"; - if (name == Names.clone && params.length == 0) - return "Clone"; - return name.toString(); - } - - private MethodBase findMethod(Symbol owner, Symbol member) { - Symbol[] ms = owner.lookup(member.name).alternativeSymbols(); - for (int i = 0; i < ms.length; i++) - if (member.info().isSameAs(ms[i].info())) { - MethodBase m = getMethod(ms[i]); - if (m != null) - return m; - } - throw Debug.abort("Couldn't find mapping for " + Debug.show(member)); - } - - private MethodBase createMethod(Symbol sym) { - MethodBase method = - createMethod((TypeBuilder)getType(sym.owner()), sym, false); - symbols2methods.put(sym, method); - setAttributes((ICustomAttributeSetter)method, global.getAttributes(sym)); - return method; - } - - - /** - * Create the method corresponding to the symbol. - - * @param isStatic - forces the created method to be static - */ - private MethodBase createMethod(TypeBuilder type, Symbol sym, boolean isStatic) - { - MethodBase method = null; - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - short attr = translateMethodAttributes(sym); - if (isStatic) - attr = (short)((attr & ~MethodAttributes.Virtual - & ~MethodAttributes.Final) - | MethodAttributes.Static); - Phase bkpCurrent = global.currentPhase; - global.currentPhase = backPhase; - Name name = sym.name; String sname = name.toString(); - switch (sym.info()) { - case PolyType(Symbol[] tparams, _): - if (tparams.length == 0) { - name = Name.fromString("get_" + name); - } - break; - default: - if (sname.endsWith("_$eq")) { - name = Name.fromString("set_" + sname - .substring(0, sname.length() - 4)); - } - } - global.currentPhase = bkpCurrent; - - return createMethod(type, name, sym.info(), attr); - default: - throw Debug.abort("Symbol doesn't have a method type: " - + Debug.show(sym)); - } - } - - - /** - * Helper method to createMethod(Symbol) - */ - private MethodBase createMethod(TypeBuilder type, Name name, - scalac.symtab.Type symType, short attr) - { - MethodBase method = null; - switch (symType) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - Type[] params = new Type[vparams.length]; - for (int i = 0; i < params.length; i++) - params[i] = getType(vparams[i]); - - if (name == Names.CONSTRUCTOR) { - ConstructorBuilder constructor = type.DefineConstructor - (attr, CallingConventions.Standard, params); - - for (int i = 0; i < vparams.length; i++) - constructor.DefineParameter - (i, ParameterAttributes.None, vparams[i].name.toString()); - return constructor; - } else { - final String sname = getMethodName(name, params); - MethodBuilder methodBuilder = type.DefineMethod - (sname, attr, getType(result), params); - - for (int i = 0; i < vparams.length; i++) - methodBuilder.DefineParameter - (i, 0/*ParameterAttributes.In*/, vparams[i].name.toString()); - return methodBuilder; - } - default: - throw Debug.abort("Method type expected: " + Debug.show(symType)); - } - } - - //########################################################################## - // find/create fields - - /** Returns the FieldInfo object corresponing to the symbol - */ - public FieldInfo getField(Symbol sym) { - FieldInfo field = (FieldInfo) symbols2fields.get(sym); - if (field != null) return field; - MemberInfo m = ti.getMember(sym); - if (m != null && m instanceof FieldInfo) { - field = (FieldInfo)m; - } else { - Type owner = getType(sym.owner()); - field = owner.GetField(sym.name.toString()); - if (field == null) { - System.out.println("Fields of class " + owner); - int bindingFlags = BindingFlags.DeclaredOnly - | BindingFlags.Instance | BindingFlags.Static - | BindingFlags.Public | BindingFlags.NonPublic; - FieldInfo[] fields = owner.GetFields(bindingFlags); - for (int i = 0; i < fields.length; i ++) - System.out.println("\t" + fields[i]); - } - } - assert field != null : "Cannot find field: " + Debug.show(sym); - symbols2fields.put(sym, field); - return field; - } - - /* - * - */ - public FieldInfo createField(Symbol sym) { - TypeBuilder owner = (TypeBuilder) getType(sym.owner()); - FieldInfo field = (FieldInfo) symbols2fields.get(sym); - if (field != null) { - assert field instanceof FieldBuilder; - return field; - } - field = owner.DefineField(sym.name.toString(), getType(sym.type()), - translateFieldAttributes(sym)); - Object o = symbols2fields.put(sym, field); - assert o == null : "Cannot re-define field: " + Debug.show(sym); - return field; - } - - /* - * - */ - private FieldInfo getModuleField(Type type) { - Symbol sym = (Symbol) types2symbols.get(type); - assert sym != null; - return getModuleField(sym); - } - - /** - * - */ - public MethodBuilder getStaticObjectMethod(Symbol sym) { - assert sym.owner().isModuleClass() : Debug.show(sym); - MethodBuilder method = (MethodBuilder)syms2staticMethods.get(sym); - assert sym != null : Debug.show(sym); - return method; - } - - private Map syms2staticTypes = new HashMap(); - - public TypeBuilder getStaticType(Symbol moduleClass) { - getType(moduleClass); // force the creation of the Type - TypeBuilder staticType = (TypeBuilder)syms2staticTypes.get(moduleClass); -// assert staticType != null : Debug.show(moduleClass) -// + " : " + syms2staticTypes; - return staticType; - } - - /* - * - */ - private Symbol getTypeSymbol(scalac.symtab.Type type) { - switch (type) { - case TypeRef(_, Symbol s, _): - return s; - default: - throw new ApplicationError("Cannot get symbol for: " - + Debug.show(type)); - } - } - - /** - * @return the field descriptor of the object instance - */ - public FieldInfo getModuleField(Symbol sym) { - assert sym.isModule() || sym.isModuleClass() : Debug.show(sym); - FieldInfo moduleField = (FieldInfo) symbols2moduleFields.get(sym); - if (moduleField == null) { - Symbol s = getTypeSymbol(sym.type()); - if (sym != s) { - moduleField = getModuleField(s); - } else { - Type type = getType(sym); - if (type instanceof TypeBuilder) { - TypeBuilder module = (TypeBuilder) type; - moduleField = module.DefineField - (MODULE_S, - module, - (short)(FieldAttributes.Public - | FieldAttributes.InitOnly - | FieldAttributes.Static)); - } else { - moduleField = type.GetField(MODULE_S); - assert moduleField != null; - } - } - symbols2moduleFields.put(sym, moduleField); - } - assert moduleField != null : Debug.show(sym); - return moduleField; - } - - //########################################################################## - // translate Scala modifiers into attributes - - /** Translates Scala modifiers into TypeAttributes - */ - private int translateTypeAttributes(Symbol clazz, boolean nested) { - int mods = clazz.flags; - int attr = TypeAttributes.AutoLayout | TypeAttributes.AnsiClass; - - if (Modifiers.Helper.isInterface(mods)) - attr |= TypeAttributes.Interface; - else - attr |= TypeAttributes.Class; - - if (Modifiers.Helper.isAbstract(mods)) - attr |= TypeAttributes.Abstract; - if (Modifiers.Helper.isFinal(mods)) - attr |= TypeAttributes.Sealed; - - if (nested) { - if (Modifiers.Helper.isPrivate(mods)) - //attr |= TypeAttributes.NestedPrivate; - // Inner classes end up in the interface of a Scala class - // and are not accessible from the implementation class. - // Giving them assembly visibility fixes the problem. - attr |= TypeAttributes.NestedAssembly; - else if (Modifiers.Helper.isProtected(mods)) - attr |= TypeAttributes.NestedFamORAssem; - else - attr |= TypeAttributes.NestedPublic; - } else { - if (Modifiers.Helper.isPrivate(mods)) - attr |= TypeAttributes.NotPublic; - else - attr |= TypeAttributes.Public; - } - boolean serializable = - global.getAttrArguments(clazz, defs.SCALA_SERIALIZABLE_CONSTR) != null - || global.getAttrArguments(clazz, SYSTEM_SERIALIZABLE_CONSTR) != null; - if (serializable) - attr |= TypeAttributes.Serializable; - return attr; - } - - /* - * Translates Scala modifiers into FieldAttributes - */ - private short translateFieldAttributes(Symbol field) { - int mods = field.flags; - int attr = 0; - - if (Modifiers.Helper.isFinal(mods)) - attr |= FieldAttributes.InitOnly; - if (Modifiers.Helper.isPrivate(mods)) - attr |= FieldAttributes.Private; - else if (Modifiers.Helper.isProtected(mods)) - attr |= FieldAttributes.FamORAssem; - else - attr |= FieldAttributes.Public; - - if (field.owner().isJava() && field.owner().isModuleClass()) - attr |= FieldAttributes.Static; - boolean tranzient = - global.getAttrArguments(field, defs.SCALA_TRANSIENT_CONSTR) != null - || global.getAttrArguments(field, SYSTEM_NONSERIALIZED_CONSTR) != null; - if (tranzient) - attr |= FieldAttributes.NotSerialized; - - return (short)attr; - } - - /* - * Translates Scala modifiers into MethodAttributes - */ - private static short translateMethodAttributes(Symbol method) - { - int mods = method.flags; - if (method.owner().isInterface()) - mods |= Modifiers.DEFERRED; - int attr = MethodAttributes.HideBySig; - if (!method.isInitializer()) { - attr |= MethodAttributes.Virtual; - if (Modifiers.Helper.isFinal(mods)) - attr |= MethodAttributes.Final; - if (Modifiers.Helper.isAbstract(mods)) - attr |= MethodAttributes.Abstract; - } - - if (Modifiers.Helper.isPrivate(mods)) - attr |= MethodAttributes.Private; - else if (Modifiers.Helper.isProtected(mods)) - attr |= MethodAttributes.Family; - else - attr |= MethodAttributes.Public; - - return (short)attr; - } - - //########################################################################## - - byte[] attributeArgs(AConstant[] args) { - ByteBuffer buf = ByteBuffer.allocate(1024); - buf.order(ByteOrder.LITTLE_ENDIAN); - buf.putShort((short)1); // write signature - for (int i = 0; i < args.length; i++) { - switch (args[i]) { - case BOOLEAN(boolean value): buf.put((byte)(value ? 1 : 0)); break; - case BYTE(byte value): buf.put(value); break; - case SHORT(short value): buf.putShort(value); break; - case CHAR(char value): buf.putChar(value); break; - case INT(int value): buf.putInt(value); break; - case LONG(long value): buf.putLong(value); break; - case FLOAT(float value): buf.putFloat(value); break; - case DOUBLE(double value): buf.putDouble(value); break; - case STRING(String value): - int length = value.length(); - if (length < 128) - buf.put((byte)length); - else if (length < 2<<14) { - buf.put((byte)((length >> 8) | 0x80)); - buf.put((byte)(length & 0xff)); - } else if (length < 2<<29) { - buf.put((byte)((length >> 24) | 0xc0)); - buf.put((byte)((length >> 16) & 0xff)); - buf.put((byte)((length >> 8) & 0xff)); - buf.put((byte)((length ) & 0xff)); - } else - throw Debug.abort("String too long: " + length); - try { - buf.put(value.getBytes("UTF-8")); - } catch (java.io.UnsupportedEncodingException e) { - throw Debug.abort(e); - } - break; - default: - throw Debug.abort("Cannot handle attribute argument " + args[i]); - } - } - buf.putShort((short)0); // count of named parameters == 0 - int length = buf.position(); - byte[] arr = new byte[length]; - System.arraycopy(buf.array(), 0, arr, 0, length); - return arr; - } - - private void setAttributes(ICustomAttributeSetter icas, AttributeInfo attr) { - for (; attr != null; attr = attr.next) { - if (!specialAttrs.contains(attr.constr)) { - ConstructorInfo constr = - (ConstructorInfo)getMethod(attr.constr); - byte[] args = attributeArgs(attr.args); - icas.SetCustomAttribute(constr, args); - } - } - } - -} // class TypeCreator diff --git a/sources/scalac/checkers/CheckTreeNodes.java.tmpl b/sources/scalac/checkers/CheckTreeNodes.java.tmpl deleted file mode 100644 index ca07b23cbd..0000000000 --- a/sources/scalac/checkers/CheckTreeNodes.java.tmpl +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.checkers; - -import scalac.Global; -import scalac.CompilerPhases; -{#Imports#} - -/** Class to check tree nodes. */ -public class CheckTreeNodes { - - //######################################################################## - // Public Constants - - public static final CheckTreeNodes instance = new CheckTreeNodes(); - - //######################################################################## - // Private Fields - - private final Global global = Global.instance; - private final CompilerPhases phases = global.PHASE; - - //######################################################################## - // Public Methods - - public void check(Tree tree) { - {#TreeSwitch#} - } - - public boolean checkNode(Tree tree) { - check(tree); - return true; - } - - //######################################################################## -} diff --git a/sources/scalac/checkers/TreeChecker.java b/sources/scalac/checkers/TreeChecker.java deleted file mode 100644 index d5e7aac987..0000000000 --- a/sources/scalac/checkers/TreeChecker.java +++ /dev/null @@ -1,637 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.checkers; - -import java.util.Iterator; -import java.util.HashSet; -import java.util.Set; -import java.util.Stack; - -import scala.tools.util.Position; - -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.AbsTypeDef; -import scalac.ast.Tree.Ident; -import scalac.ast.Tree.Template; -import scalac.ast.Tree.ValDef; -import scalac.ast.TreeInfo; -import scalac.symtab.Definitions; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This checker checks that trees are well-formed. It checks both the - * shape and the attribution of the trees. WARNING: currently, the - * checks are valid only for trees generated by phase AddConstructors. - */ -public class TreeChecker { - - //######################################################################## - // Private Fields - - /** The global definitions */ - private final Definitions definitions; - - /** The stack of current units */ - private final Stack/*<CompilationUnit>*/ units = new Stack(); - - /** The stack of current classes */ - private final Stack/*<Symbol>*/ classes = new Stack(); - - /** The stack of current members */ - private final Stack/*<Symbol>*/ members = new Stack(); - - /** The stack of current owners */ - private final Stack/*<Symbol>*/ owners = new Stack(); - - /** The currently visible type variables */ - private final Set/*<Symbol>*/ tvars = new HashSet(); - - /** The currently visible value variables */ - private final Set/*<Symbol>*/ vvars = new HashSet(); - - /** The currently visible labels */ - private final Set/*<Symbol>*/ labels = new HashSet(); - - /** The currently defined symbols */ - private final Set/*<Symbol>*/ symbols = new HashSet(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public TreeChecker(Definitions definitions) { - this.definitions = definitions; - } - - //######################################################################## - // Public Methods - Checking units - - /** Checks the unit. Returns true. */ - public boolean check(CompilationUnit unit) { - pushUnit(unit); - template(unit.body); - popUnit(); - return true; - } - - //######################################################################## - // Private Methods - Checking templates - - /** Checks the templates. Returns true. */ - private boolean template(Tree[] trees) { - for (int i = 0; i < trees.length; i++) template(trees[i]); - return true; - } - - /** Checks the template. Returns true. */ - private boolean template(Tree tree) { - switch (tree) { - - case Empty: - return true; - - case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, _, Template(_, Tree[] body)): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isClass(): show(tree); - assert vparams.length == 1: show(tree); - containSymbols(tparams, symbol.typeParams()); - containSymbols(vparams[0],symbol.valueParams()); - registerSymbol(symbol); - scopeInsertParametersOf(symbol); - pushClass(symbol); - member(body); - popClass(); - scopeRemoveParametersOf(symbol); - return true; - - case PackageDef(Tree packaged, Template(Tree[] bases, Tree[] body)): - Symbol symbol = packaged.symbol(); - assert symbol != null && symbol.isPackage(): show(packaged); - assert bases.length == 0: show(tree); - pushOwner(symbol); - template(body); - popOwner(); - return true; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Checking members - - /** Checks the members. Returns true. */ - private boolean member(Tree[] trees) { - for (int i = 0; i < trees.length; i++) member(trees[i]); - return true; - } - - /** Checks the member. Returns true. */ - private boolean member(Tree tree) { - switch (tree) { - - case Empty: - return true; - - case ClassDef(_, _, _, _, _, _): - return template(tree); - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - assert rhs == Tree.Empty: show(tree); - registerSymbol(symbol); - pushMember(symbol); - popMember(); - return true; - - case DefDef(_, _, AbsTypeDef[]tparams, ValDef[][]vparams, _, Tree rhs): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isMethod(): show(tree); - assert vparams.length == 1: show(tree); - containSymbols(tparams, symbol.typeParams()); - containSymbols(vparams[0],symbol.valueParams()); - assert symbol.isDeferred() == (rhs == Tree.Empty): show(tree); - registerSymbol(symbol); - scopeInsertParametersOf(symbol); - pushMember(symbol); - if (!symbol.isDeferred()) expression(rhs, symbol.resultType()); - popMember(); - scopeRemoveParametersOf(symbol); - return true; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Checking statements - - /** Checks the statement. Returns true. */ - private boolean statement(Set locals, Tree tree) { - switch (tree) { - - case Empty: - return true; - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - scopeInsertVVariable(symbol, false); - locals.add(symbol); - pushOwner(symbol); - expression(rhs, symbol.type()); - popOwner(); - return true; - - default: - return expression(tree, tree.type()); - } - } - - //######################################################################## - // Private Methods - Checking expressions - - /** Checks the expression of given expected type. Returns true. */ - private boolean expression(Tree tree, Type expected) { - // !!! conforms(tree, expected); - expected = tree.type(); - switch (tree) { - - case LabelDef(_, Ident[] idents, Tree rhs): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isLabel(): show(tree); - Symbol[] params = symbol.type().valueParams(); - assert params.length == idents.length: show(tree) - + format("params", Debug.show(params)); - for (int i = 0; i < idents.length; i++) { - location(idents[i]); - conforms(idents[i], definitions.ANY_TYPE(), params[i].type()); - Symbol local = idents[i].symbol(); - assert local != null && !local.isModule(): show(idents[i]); - } - conforms(tree, symbol.resultType()); - scopeInsertLabel(symbol); - expression(rhs, symbol.resultType()); - scopeRemoveLabel(symbol); - return true; - - case Block(Tree[] statements, Tree value): - Set locals = new HashSet(); - for (int i = 0; i < statements.length; i++) - statement(locals, statements[i]); - expression(value, expected); - for (Iterator i = locals.iterator(); i.hasNext(); ) - scopeRemoveVVariable((Symbol)i.next()); - return true; - - case Assign(Tree lhs, Tree rhs): - location(lhs); - expression(rhs, lhs.type().widen()); - return true; - - case If(Tree cond, Tree thenp, Tree elsep): - expression(cond, definitions.boolean_TYPE()); - expression(thenp, expected); - expression(elsep, expected); - return true; - - case Switch(Tree test, _, Tree[] bodies, Tree otherwise): - expression(test, definitions.int_TYPE()); - for (int i = 0; i < bodies.length; i++) - expression(bodies[i], expected); - expression(otherwise, expected); - return true; - - case Return(Tree value): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isMethod(): show(tree); - assert currentMember() == symbol: show(tree); - return expression(value, currentMember().resultType()); - - case Throw(Tree value): - return expression(value, definitions.THROWABLE_TYPE()); - - case New(Tree init): - switch (init) { - case Apply(Select(Create(_, Tree[] targs), _), Tree[] vargs): - return expression(init, definitions.void_TYPE()); - default: - throw Debug.abort("illegal case", show(tree)); - } - - case Create(Tree qualifier, Tree[] targs): - assert qualifier == Tree.Empty: show(tree); - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isClass(): show(tree); - return true; - - case Apply(Tree vfun, Tree[] vargs): - vapply(tree, vfun.type(), vargs); - switch (vfun) { - case TypeApply(Tree tfun, Tree[] targs): - Symbol symbol = tfun.symbol(); - assert symbol != null && !symbol.isLabel(): show(tree); - tapply(tree, tfun.type(), targs); - return function(tfun); - default: - return function(vfun); - } - - case Super(_, _): - case This(_): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isClass(): show(tree); - assert symbol == currentClass(): show(tree); - return true; - - case Select(_, _): - case Ident(_): - return location(tree); - - case Literal(_): - return true; - - default: - throw Debug.abort("illegal case", show(tree)); - } - } - - /** Checks the type application. Returns true. */ - private boolean tapply(Tree tree, Type function, Tree[] args) { - Symbol[] params = function.typeParams(); - assert params.length == args.length: show(tree) - + format("params", Debug.show(params)); - Type.Map subst = Type.getSubst(params, Tree.typeOf(args)); - for (int i = 0; i < args.length; i++) { - Type expected = subst.apply(params[i].info()); - Type loBound = subst.apply(params[i].loBound()); - conforms(args[i], expected, loBound); - } - conforms(tree, subst.apply(function.resultType())); - return true; - } - - /** Checks the value application. Returns true. */ - private boolean vapply(Tree tree, Type function, Tree[] args) { - Symbol[] params = function.valueParams(); - assert params.length == args.length: show(tree) - + format("params", Debug.show(params)); - for (int i = 0; i < args.length; i++) - expression(args[i], params[i].type()); - conforms(tree, function.resultType()); - return true; - } - - //######################################################################## - // Private Methods - Checking functions - - /** Checks the function. Returns true. */ - private boolean function(Tree tree) { - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - assert symbol.isMethod(): show(tree); - switch (tree) { - - case Select(Tree qualifier, _): - if (qualifier instanceof Tree.Create) - assert symbol.isInitializer(): show(tree); - return selection(tree); - - case Ident(_): - if (!symbol.isLabel() && symbol.isStatic()) return true; - assert labels.contains(symbol): show(tree); - assert symbol.owner() == currentMember(): show(tree); - return true; - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Checks the location. Returns true. */ - private boolean location(Tree tree) { - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - assert !symbol.isMethod(): show(tree); - switch (tree) { - - case Select(_, _): - return selection(tree); - - case Ident(_): - if (symbol.isStatic()) return true; - assert vvars.contains(symbol): show(tree); - assert symbol.owner() == currentMember(): show(tree); - return true; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Checking selection - - /** Checks the selection. Returns true. */ - private boolean selection(Tree tree) { - switch (tree) { - - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - Symbol owner = symbol.owner(); - assert owner.isClass() && !owner.isStaticOwner(): show(tree); - assert qualifier.type().baseType(owner) != Type.NoType: - show(tree) + format("qual.type", qualifier.type()); - return expression(qualifier, qualifier.type()); - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Checking helpers - - /** Do the trees contain the given symbols? */ - private void containSymbols(Tree[] trees, Symbol[] symbols) { - boolean ok = trees.length == symbols.length; - for (int i = 0; ok && i < trees.length; i++) - ok &= trees[i].symbol() == symbols[i]; - assert ok: show() + format("trees", trees) + format("symbols",symbols); - } - - /** Does the type conform to the expected type and lower bound? */ - private void conforms(Tree tree, Type expected, Type loBound) { - conforms(tree, expected); - if (false && !loBound.isSubType(tree.type())) { // !!! false && - Type.explainSwitch = true; - assert loBound.isSubType(tree.type()): show(tree) - + format("loBound", expected); - Type.explainSwitch = false; - } - } - - /** Does the type conform to the expected type? */ - private void conforms(Tree tree, Type expected) { - if (!tree.type().isSubType(expected)) { - Type.explainSwitch = true; - assert tree.type().isSubType(expected): show(tree) - + format("expected", expected); - Type.explainSwitch = false; - } - } - - //######################################################################## - // Private Methods - Declaring symbols - - /** Remove parameters of symbol from current scope. */ - private void scopeInsertParametersOf(Symbol symbol) { - Symbol[] tparams = symbol.typeParams(); - for (int i = 0; i < tparams.length; i++) - scopeInsertTVariable(tparams[i], true); - Symbol[] vparams = symbol.valueParams(); - for (int i = 0; i < vparams.length; i++) - scopeInsertVVariable(vparams[i], true); - } - - /** Adds the type variable to the current scope. */ - private void scopeInsertTVariable(Symbol symbol, boolean isParameter) { - assert !symbol.owner().isClass(): show(symbol); - assert symbol.isParameter() == isParameter: show(symbol); - registerSymbol(symbol); - tvars.add(symbol); - } - - /** Adds the value variable to the current scope. */ - private void scopeInsertVVariable(Symbol symbol, boolean isParameter) { - assert !symbol.owner().isClass(): show(symbol); - assert symbol.isParameter() == isParameter: show(symbol); - registerSymbol(symbol); - vvars.add(symbol); - } - - /** Adds the label to current scope. */ - private void scopeInsertLabel(Symbol symbol) { - assert !symbol.owner().isClass(): show(symbol); - registerSymbol(symbol); - labels.add(symbol); - } - - /** Remove parameters of symbol from current scope. */ - private void scopeRemoveParametersOf(Symbol symbol) { - Symbol[] tparams = symbol.typeParams(); - for (int i = 0; i < tparams.length; i++) - scopeRemoveTVariable(tparams[i]); - Symbol[] vparams = symbol.valueParams(); - for (int i = 0; i < vparams.length; i++) - scopeRemoveVVariable(vparams[i]); - } - - /** Removes the type variable from current scope. */ - private void scopeRemoveTVariable(Symbol symbol) { - boolean removed = tvars.remove(symbol); - assert removed: show(symbol); - } - - /** Removes the value variable from current scope. */ - private void scopeRemoveVVariable(Symbol symbol) { - boolean removed = vvars.remove(symbol); - assert removed: show(symbol); - } - - /** Removes the label symbol from current scope. */ - private void scopeRemoveLabel(Symbol symbol) { - boolean removed = labels.remove(symbol); - assert removed: show(symbol); - } - - /** Registers the symbol. */ - private void registerSymbol(Symbol symbol) { - boolean added = symbols.add(symbol); - assert added: show(symbol); - } - - //######################################################################## - // Private Methods - Managing current context - - /** Returns the current unit. */ - private CompilationUnit currentUnit() { - return units.size() > 0 ? (CompilationUnit)units.peek() : null; - } - - /** Returns the current class. */ - private Symbol currentClass() { - return classes.size() > 0 ? (Symbol)classes.peek() : null; - } - - /** Returns the current member. */ - private Symbol currentMember() { - return members.size() > 0 ? (Symbol)members.peek() : null; - } - - /** Returns the current owner. */ - private Symbol currentOwner() { - return owners.size() > 0 ? (Symbol)owners.peek() : null; - } - - /** Sets the current unit to the given one. */ - private void pushUnit(CompilationUnit unit) { - assert units.size() == 0: showPush(unit); - assert classes.size() == 0: showPush(unit); - assert members.size() == 0: showPush(unit); - units.push(unit); - } - - /** Sets the current class to the given one. */ - private void pushClass(Symbol clasz) { - assert clasz.isClass(): showPush(clasz); - assert members.size() == 0: showPush(clasz); - classes.push(clasz); - pushOwner(clasz); - } - - /** Sets the current member to the given one. */ - private void pushMember(Symbol member) { - assert member.isTerm(): showPush(member); - assert members.size() == 0: showPush(member); - assert member.owner() == currentClass(): showPush(member); - members.push(member); - pushOwner(member); - } - - /** Sets the current owner to the given one. */ - private void pushOwner(Symbol owner) { - owners.push(owner); - } - - /** Sets the current unit to the previous one. */ - private void popUnit() { - assert units.size() > 0: show(); - units.pop(); - } - - /** Sets the current class to the previous one. */ - private void popClass() { - assert members.size() == 0: show(); - assert classes.size() > 0: show(); - popOwner(); - classes.pop(); - } - - /** Sets the current member to the previous one. */ - private void popMember() { - assert members.size() > 0: show(); - popOwner(); - members.pop(); - } - - /** Sets the current owner to the previous one. */ - private void popOwner() { - assert owners.size() > 0: show(); - owners.pop(); - } - - //######################################################################## - // Private Methods - Showing errors - - /** Returns the current position. */ - private String show() { - return format("unit", currentUnit()) - + format("clasz", currentClass()) - + format("member", currentMember()) - + format("owner", currentOwner()); - } - - /** Returns the current position and given header and value. */ - private String show(String header, Object value) { - return show() + format(header, value); - } - - /** Returns the current position and given symbol. */ - private String show(Symbol symbol) { - return show("symbol", symbol) - + format("symbol.pos", Position.toString(symbol.pos)) - + format("symbol.info", symbol.info()); - } - - /** Returns the current position and given tree. */ - private String show(Tree tree) { - return show("tree", tree) - + format("tree.pos", Position.toString(tree.pos)) - + format("tree.symbol", tree.symbol()) - + format("tree.type", tree.type()); - } - - /** Returns the current position and given pushed value. */ - private String showPush(Object value) { - return show("pushing", value); - } - - /** Returns a string with the given header and value. */ - private String format(String header, Object value) { - while (header.length() < 12) header = header + ' '; - return "\n" + header + ": " + toString(value); - } - - /** Returns a string representation of the given value. */ - private String toString(Object value) { - if (value instanceof Symbol) return Debug.show(value); - if (value instanceof Object[]) return Debug.show(value); - return String.valueOf(value); - } - - //######################################################################## -} diff --git a/sources/scalac/framework/History.java b/sources/scalac/framework/History.java deleted file mode 100644 index ce0800358d..0000000000 --- a/sources/scalac/framework/History.java +++ /dev/null @@ -1,277 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.framework; - -import scalac.Global; -import scalac.Phase; -import scalac.util.Debug; - -/** - * This class implements a value history. It stores phase dependent - * values. - * - * Implementation: the value "values[n]" is valid from start of phase - * "starts[n]" to end of phase "(n == 0 ? limit : starts[n-1].prev)" - * and the promised value "next" is valid from start of phase - * "limit.next". - */ -public class History { - - //######################################################################## - // Private Constants - - /** An empty array of objects */ - private static final Object[] NO_VALUES = new Object[0]; - - /** An empty array of phases */ - private static final Phase[] NO_STARTS = new Phase[0]; - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The successive values of this history */ - private Object[] values; - - /** The start phases of the successive values */ - private Phase[] starts; - - /** The last known valid phase of the last value */ - private Phase limit; - - /** A promise of the next value (may be null) */ - private Promise next; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with current phase as first one. */ - public History() { - this(Global.instance); - } - - /** Initializes this instance with current phase as first one. */ - public History(Global global) { - this(global, global.currentPhase); - } - - /** Initializes this instance with given first phase. */ - public History(Phase first) { - this(first.global, first); - } - - /** Initializes this instance with given first phase. */ - public History(Global global, Phase first) { - this.global = global; - reset(first); - } - - //######################################################################## - // Public Methods - - /** Returns the first phase of this history. */ - public final Phase getFirstPhase() { - return starts.length > 0 ? starts[starts.length - 1] : limit.next; - } - - /** Returns the value at current phase. */ - public final Object getValue(Object owner) { - return getValueAt(owner, getPhase()); - } - - /** Returns the value at next phase. */ - public final Object getNextValue(Object owner) { - return getValueAt(owner, getNextPhase()); - } - - /** Returns the value at given phase. */ - public final Object getValueAt(Object owner, Phase phase) { - assert phase != null: show(owner, phase); - while (limit.id < phase.id) incrementLimit(owner); - for (int i = 0; i < starts.length; i++) - if (starts[i].id <= phase.id) return values[i]; - throw Debug.abort("prehistoric phase", show(owner, phase)); - } - - /** Sets the value at current phase. */ - public final History setValue(Object owner, Object value) { - return setValueAt(owner, getPhase(), value); - } - - /** Sets the value at next phase. */ - public final History setNextValue(Object owner, Object value) { - return setValueAt(owner, getNextPhase(), value); - } - - /** Sets the value at given phase. */ - public final History setValueAt(Object owner, Phase phase, Object value) { - assert phase != null: show(owner, phase); - assert phase == limit.next && next == null: show(owner, phase); - if (values.length == 0 || values[0] != value) { - this.values = append(value, values); - this.starts = append(phase, starts); - } - this.limit = phase; - return this; - } - - /** Sets a value promise at current phase. */ - public final History setPromise(Object owner, Promise promise) { - return setPromiseAt(owner, getPhase(), promise); - } - - /** Sets a value promise at next phase. */ - public final History setNextPromise(Object owner, Promise promise) { - return setPromiseAt(owner, getNextPhase(), promise); - } - - /** Sets a value promise at given phase. */ - public final History setPromiseAt(Object owner, Phase phase, - Promise promise) - { - assert phase != null: show(owner, phase); - assert phase == limit.next && next == null: show(owner, phase); - this.next = promise; - return this; - } - - /** Erases all values. */ - public final void reset() { - reset(getFirstPhase()); - } - - /** Erases all values and sets first phase to given one. */ - public final void reset(Phase first) { - assert first != null && first.prev != null: this + " - " + first; - this.values = NO_VALUES; - this.starts = NO_STARTS; - this.limit = first.prev; - this.next = null; - } - - /** Returns a string representation of this history. */ - public String toString() { - StringBuffer buffer = new StringBuffer("["); - for (int i = 0; i < values.length; i++) { - buffer.append(starts[i]).append(" -> "); - buffer.append(Debug.show(values[i])).append(", "); - } - buffer.append(limit); - if (next != null) buffer.append(" - ").append(next); - return buffer.append("]").toString(); - } - - //######################################################################## - // Protected Methods - - /** - * Computes the value at phase following given one by transforming - * the given value (which is the value at given phase). The - * default implementation changes the current phase to given one - * and then forwards the call to method "transformValue". - */ - protected Object transformValueAt(Object owner, Phase phase, Object value){ - Phase current = global.currentPhase; - global.currentPhase = phase; - Object result = transformValue(owner, value); - global.currentPhase = current; - return result; - } - - /** - * Computes the value at next phase by transforming the given - * value (which is the value at current phase). The default - * implementation forwards the call to method "computeValueAt". - */ - protected Object transformValue(Object owner, Object value) { - return computeValueAt(owner, global.currentPhase.next); - } - - /** - * Computes the value at given phase. The default implementation - * changes the current phase to given one and then forwards the - * call to method "computeValue". - */ - protected Object computeValueAt(Object owner, Phase phase) { - Phase current = global.currentPhase; - global.currentPhase = phase; - Object result = computeValue(owner); - global.currentPhase = current; - return result; - } - - /** - * Computes the value at current phase. The default implementation - * throws an exception. - */ - protected Object computeValue(Object owner) { - throw Debug.abort("undefined value", show(owner, getPhase())); - } - - //######################################################################## - // Private Methods - - /** Returns the current phase. */ - private Phase getPhase() { - return global.currentPhase; - } - - /** Returns the next phase. */ - private Phase getNextPhase() { - return getPhase().next; - } - - /** Increments the limit of this history. */ - private void incrementLimit(Object owner) { - Phase phase = limit; - Object value; - if (next != null) { - value = next.forceAt(owner, global, phase.next); - if (limit == phase) next = null; - } else if (values.length > 0) { - value = transformValueAt(owner, phase, values[0]); - } else { - value = computeValueAt(owner, phase.next); - } - if (limit == phase) setValueAt(owner, phase.next, value); - } - - /** Returns a string of this history and given owner. */ - private String show(Object owner) { - return this + " @ " + Debug.show(owner); - } - - /** Returns a string of this history and given owner and phase. */ - private String show(Object owner, Phase phase) { - return show(owner) + " - " + phase; - } - - //######################################################################## - // Private Functions - - /** Returns the concatenation of given values. */ - private static Object[] append(Object value, Object[] values) { - Object[] array = new Object[1 + values.length]; - array[0] = value; - for (int i = 1; i < array.length; i++) array[i] = values[i - 1]; - return array; - } - - /** Returns the concatenation of given phases. */ - private static Phase[] append(Phase phase, Phase[] phases) { - Phase[] array = new Phase[1 + phases.length]; - array[0] = phase; - for (int i = 1; i < array.length; i++) array[i] = phases[i - 1]; - return array; - } - - //######################################################################## -} diff --git a/sources/scalac/framework/Promise.java b/sources/scalac/framework/Promise.java deleted file mode 100644 index 7a1a521512..0000000000 --- a/sources/scalac/framework/Promise.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.framework; - -import scalac.Global; -import scalac.Phase; - -/** - * This abstract class represents a value promise (a lazy value). The - * promised value is obtained by invoking the method "force" which - * will detect any cyclic definition. Note that this class does not - * store evaluated values. Therefore, successive calls to "force" will - * trigger successive evaluations of the promise. - */ -public abstract class Promise { - - //######################################################################## - // Private Fields - - /** The current number of evaluation cycles */ - private int cycles; - - //######################################################################## - // Public Methods - - /** Forces this promise and returns its value. */ - public final Object force(Object owner) { - int cycles = this.cycles; - this.cycles++; - Object value = cycles > 0 - ? evaluate(owner) - : getCyclicValue(owner, cycles); - this.cycles--; - return value; - } - - /** Forces this promise at given phase and returns its value. */ - public final Object forceAt(Object owner, Global global, Phase phase) { - Phase current = global.currentPhase; - global.currentPhase = phase; - Object value = force(owner); - global.currentPhase = current; - return value; - } - - //######################################################################## - // Protected Methods - - /** - * Evaluates this promise. This method is invoked by non-cyclic - * calls to the method "force". - */ - protected abstract Object evaluate(Object owner); - - /** - * Returns the value to use in case of a cyclic definition. This - * method is invoked by cyclic calls to the method "force". The - * current (strictly positive) number of cycles is passed as an - * argument. - */ - protected abstract Object getCyclicValue(Object owner, int cycles); - - //######################################################################## -} diff --git a/sources/scalac/symtab/AttributeInfo.java b/sources/scalac/symtab/AttributeInfo.java deleted file mode 100644 index 00d7c22d5a..0000000000 --- a/sources/scalac/symtab/AttributeInfo.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import scalac.atree.AConstant; -import scalac.util.Debug; - -public class AttributeInfo { - - public final Symbol constr; - public final AConstant[] args; - public final AttributeInfo next; - - public AttributeInfo(Symbol constr, AConstant[] args, AttributeInfo next) { - this.constr = constr; - this.args = args; - this.next = next; - assert constr.isConstructor() : Debug.show(constr); - } - - public AConstant[] getAttrArguments(Symbol sym) { - for (AttributeInfo attr = this; attr != null; attr = attr.next) - if (attr.constr == sym) - return attr.args; - return null; - } - - public String toString() { - StringBuffer str = new StringBuffer("["); - for (AttributeInfo attr = this; attr != null; attr = attr.next) { - str.append(Debug.show(attr.constr.constructorClass())); - int n = attr.args.length; - if (n > 0) { - str.append('('); - for (int i = 0; i < n; i++) { - if (i > 0) str.append(", "); - str.append(attr.args[i]); - } - str.append(')'); - } - if (attr.next != null) { - str.append(", "); - } - } - str.append(']'); - return str.toString(); - } - -} diff --git a/sources/scalac/symtab/ClosureHistory.java b/sources/scalac/symtab/ClosureHistory.java deleted file mode 100644 index 0f5073cd89..0000000000 --- a/sources/scalac/symtab/ClosureHistory.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.util.Iterator; -import java.util.TreeMap; - -import scalac.Global; -import scalac.framework.History; -import scalac.util.Debug; -import scalac.util.ArrayApply; - -/** This class implements a closure history. */ -public class ClosureHistory extends History { - - //######################################################################## - // Protected Methods - - /** Transforms given closure into closure at next phase. */ - protected Object transformValue(Object owner, Object value){ - Type[] closure = (Type[])value; - for (int i = 0; i < closure.length; i++) { - Symbol symbol = closure[i].symbol(); - // !!! symbol.nextInfoHasChanged() would be better - if (symbol.info() != symbol.nextInfo()) - return super.transformValue(owner, closure); - } - return closure; - } - - /** Computes the closure at current phase. */ - protected Object computeValue(Object owner) { - Symbol clasz = (Symbol)owner; - TreeMap parents = new TreeMap(SymbolComparator.instance); - addParents(parents, clasz.info()); - Type[] closure = new Type[1 + parents.size()]; - Iterator types = parents.values().iterator(); - closure[0] = clasz.type(); - for (int i = 1; i < closure.length; i++) - closure[i] = (Type)types.next(); - //System.out.println("closure(" + owner + ") = " + ArrayApply.toString(closure));//DEBUG - return closure; - } - - //######################################################################## - // Private Functions - - /** Adds all parents of given type to given parent table. */ - private static void addParents(TreeMap/*<Symbol,Type>*/ table, Type type) { - switch (type) { - case ErrorType: case NoType: - return; - case TypeRef(_, Symbol symbol, _): - Type.Map map = Type.getThisTypeMap(symbol, type); - Type[] closure = symbol.closure(); - for (int i = 0; i < closure.length; i++) - table.put(closure[i].symbol(), map.apply(closure[i])); - return; - case CompoundType(Type[] parents, _): - for (int i = 0; i < parents.length; i++) - addParents(table, parents[i]); - return; - case SingleType(_, _): - case ThisType(_): - addParents(table, type.singleDeref()); - return; - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java deleted file mode 100644 index d100e911c8..0000000000 --- a/sources/scalac/symtab/Definitions.java +++ /dev/null @@ -1,1194 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - -import scala.tools.util.Position; - -import scalac.Global; -import scalac.atree.ATreeTyper; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; - -public class Definitions { - - //######################################################################## - // Public Fields - Root module - - /** The attributed tree typer */ - public final ATreeTyper atyper; - - //######################################################################## - // Public Fields & Methods - Root class and some standard packages - - /** The root class */ - public final Symbol ROOT_CLASS; - - /** The java.lang package */ - public final Symbol JAVALANG; - - /** The scala package */ - public final Symbol SCALA; - - //######################################################################## - // Public Fields & Methods - Top and bottom classes - - /** The scala.Any class */ - public final Symbol ANY_CLASS; - public final Type ANY_TYPE() {return ANY_CLASS.staticType();} - - /** The scala.AnyVal class */ - public final Symbol ANYVAL_CLASS; - public final Type ANYVAL_TYPE() {return ANYVAL_CLASS.staticType();} - - /** The scala.AnyRef class */ - public final Symbol ANYREF_CLASS; - public final Type ANYREF_TYPE() {return ANYREF_CLASS.staticType();} - - /** The scala.AllRef class */ - public final Symbol ALLREF_CLASS; - public final Type ALLREF_TYPE() {return ALLREF_CLASS.staticType();} - - /** The scala.All class */ - public final Symbol ALL_CLASS; - public final Type ALL_TYPE() {return ALL_CLASS.staticType();} - - //######################################################################## - // Public Fields & Methods - Java classes - - /** The java.lang.Object class */ - public final Symbol OBJECT_CLASS; - public final Type OBJECT_TYPE() {return OBJECT_CLASS.staticType();} - - /** The java.lang.String class */ - public final Symbol STRING_CLASS; - public final Type STRING_TYPE() {return STRING_CLASS.staticType();} - - /** The java.lang.Throwable class */ - public final Symbol THROWABLE_CLASS; - public final Type THROWABLE_TYPE() {return THROWABLE_CLASS.staticType();} - - //######################################################################## - // Public Fields & Methods - Scala value classes - - /** The scala.Unit class */ - public final Symbol UNIT_CLASS; - public final Type UNIT_TYPE() {return UNIT_CLASS.staticType();} - - /** The scala.Boolean class */ - public final Symbol BOOLEAN_CLASS; - public final Type BOOLEAN_TYPE() {return BOOLEAN_CLASS.staticType();} - - /** The scala.Byte class */ - public final Symbol BYTE_CLASS; - public final Type BYTE_TYPE() {return BYTE_CLASS.staticType();} - - /** The scala.Short class */ - public final Symbol SHORT_CLASS; - public final Type SHORT_TYPE() {return SHORT_CLASS.staticType();} - - /** The scala.Char class */ - public final Symbol CHAR_CLASS; - public final Type CHAR_TYPE() {return CHAR_CLASS.staticType();} - - /** The scala.Int class */ - public final Symbol INT_CLASS; - public final Type INT_TYPE() {return INT_CLASS.staticType();} - - /** The scala.Long class */ - public final Symbol LONG_CLASS; - public final Type LONG_TYPE() {return LONG_CLASS.staticType();} - - /** The scala.Float class */ - public final Symbol FLOAT_CLASS; - public final Type FLOAT_TYPE() {return FLOAT_CLASS.staticType();} - - /** The scala.Double class */ - public final Symbol DOUBLE_CLASS; - public final Type DOUBLE_TYPE() {return DOUBLE_CLASS.staticType();} - - - //######################################################################## - // Public Fields & Methods - Scala reference classes - - /** The scala.ScalaObject class */ - public final Symbol SCALAOBJECT_CLASS; - public final Type SCALAOBJECT_TYPE() {return SCALAOBJECT_CLASS.staticType();} - - /** The scala.Attribute class */ - public final Symbol ATTRIBUTE_CLASS; - public final Type ATTRIBUTE_TYPE() {return ATTRIBUTE_CLASS.staticType();} - - /** The scala.Ref class */ - public final Symbol REF_CLASS; - public final Type REF_TYPE(Type element) { - return REF_CLASS.staticType(element); - } - - /** The scala.TupleX classes */ - public final int TUPLE_COUNT = 10; - public final Symbol[] TUPLE_CLASS = new Symbol[TUPLE_COUNT]; - public final Type TUPLE_TYPE(Type[] args) { - assert 0 < args.length && args.length < TUPLE_COUNT: args.length; - return TUPLE_CLASS[args.length].staticType(args); - } - - /** The scala.FunctionX classes */ - public final int FUNCTION_COUNT = 10; - public final Symbol[] FUNCTION_CLASS = new Symbol[FUNCTION_COUNT]; - public final Type FUNCTION_TYPE(Type[] args, Type result) { - assert 0 <= args.length; - if (args.length >= FUNCTION_COUNT) - throw new Type.Error("function has too many arguments; limit = " + (FUNCTION_COUNT-1)); - args = Type.cloneArray(args, 1); - args[args.length - 1] = result; - return FUNCTION_CLASS[args.length - 1].staticType(args); - } - - /** The scala.PartialFunction class */ - public final Symbol PARTIALFUNCTION_CLASS; - public final Type PARTIALFUNCTION_TYPE(Type argument, Type result) { - return PARTIALFUNCTION_CLASS.staticType(argument, result); - } - - /** The scala.Iterable class */ - public final Symbol ITERABLE_CLASS; - public final Type ITERABLE_TYPE(Type element) { - return ITERABLE_CLASS.staticType(element); - } - - /** The scala.Iterator class */ - public final Symbol ITERATOR_CLASS; - public final Type ITERATOR_TYPE(Type element) { - return ITERATOR_CLASS.staticType(element); - } - - /** The scala.Seq class */ - public final Symbol SEQ_CLASS; - public final Type SEQ_TYPE(Type element) { - return SEQ_CLASS.staticType(element); - } - - /** The scala.List class */ - public final Symbol LIST_CLASS; - public final Type LIST_TYPE(Type element) { - return LIST_CLASS.staticType(element); - } - - /** The scala.Nil module - * evaluated on demand to make bootstrap possible. - */ - public final Symbol NIL() { - return getModule("scala.Nil"); - } - - /** The scala.:: class - * evaluated on demand to make bootstrap possible. - */ - public final Symbol CONS_CLASS() { - return getClass("scala.$colon$colon"); - } - public final Type CONS_TYPE(Type element) { - return CONS_CLASS().staticType(element); - } - - /** The scala.Array class */ - public final Symbol ARRAY_CLASS; - public final Type ARRAY_TYPE(Type element) { - return ARRAY_CLASS.staticType(element); - } - - /** The scala.Type class & its subclasses */ - public final Symbol TYPE_CLASS; - public final Type TYPE_TYPE() { - return TYPE_CLASS.staticType(); - } - - public final Symbol CLASSTYPE_CLASS; - public final Type CLASSTYPE_TYPE() { - return CLASSTYPE_CLASS.staticType(); - } - - public final Symbol JAVACLASSTYPE_CLASS; - public final Symbol JAVAREFARRAYTYPE_CLASS; - - public final Symbol SCALACLASSTYPE_CLASS; - public final Type SCALACLASSTYPE_TYPE() { - return SCALACLASSTYPE_CLASS.staticType(); - } - - public final Symbol SINGLETYPE_CLASS; - - public final Symbol TYPECONSTRUCTOR_CLASS; - public final Type TYPECONSTRUCTOR_TYPE() { - return TYPECONSTRUCTOR_CLASS.staticType(); - } - - public final Symbol COMPOUNDTYPE_CLASS; - - public final Symbol LAZYPARENTS_CLASS; - public final Type LAZYPARENTS_TYPE() { - return LAZYPARENTS_CLASS.staticType(); - } - - /** The scala.Predef module */ - public final Symbol PREDEF; - - /** The scala.Console module */ - public final Symbol CONSOLE; - - /** The scala.MatchError module */ - public final Symbol MATCHERROR; - - //######################################################################## - // attributes - - public final Symbol SCALA_SERIALIZABLE_CONSTR; - public final Symbol SCALA_TRANSIENT_CONSTR; - public final Symbol SCALA_VOLATILE_CONSTR; - public final Symbol SCALA_CLONEABLE_CONSTR; - - //######################################################################## - // Public Fields & Methods - Scala primitive types - - /** Returns the primitive type void. */ - public final Type void_TYPE() { - return void_TYPE.type().resultType(); - } - - /** Returns the primitive type boolean. */ - public final Type boolean_TYPE() { - return boolean_TYPE.type().resultType(); - } - - /** Returns the primitive type byte. */ - public final Type byte_TYPE() { - return byte_TYPE.type().resultType(); - } - - /** Returns the primitive type short. */ - public final Type short_TYPE() { - return short_TYPE.type().resultType(); - } - - /** Returns the primitive type char. */ - public final Type char_TYPE() { - return char_TYPE.type().resultType(); - } - - /** Returns the primitive type int. */ - public final Type int_TYPE() { - return int_TYPE.type().resultType(); - } - - /** Returns the primitive type long. */ - public final Type long_TYPE() { - return long_TYPE.type().resultType(); - } - - /** Returns the primitive type float. */ - public final Type float_TYPE() { - return float_TYPE.type().resultType(); - } - - /** Returns the primitive type double. */ - public final Type double_TYPE() { - return double_TYPE.type().resultType(); - } - - /** Returns the primitive array type of given element type. */ - public final Type array_TYPE(Type element) { - Type type = array_TYPE.type().resultType(); - switch (type) { - case TypeRef(Type prefix, Symbol clasz, _): - return Type.typeRef(prefix, clasz, new Type[]{element}); - case UnboxedArrayType(_): - return Type.UnboxedArrayType(element); - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## - // Public Fields & Methods - Top and bottom class methods - - /** Some scala.Any methods */ - public final Symbol ANY_EQEQ; - public final Symbol ANY_BANGEQ; - public final Symbol ANY_EQUALS; - public final Symbol ANY_HASHCODE; - public final Symbol ANY_TOSTRING; - //public final Symbol ANY_PLUS; - public final Symbol ANY_IS; - public final Symbol ANY_IS_ERASED; - public final Symbol ANY_AS; - public final Symbol ANY_AS_ERASED; - public final Symbol ANY_MATCH; - - //######################################################################## - // Public Fields & Methods - Java class methods - - /** Some java.lang.Object methods */ - public final Symbol OBJECT_EQ; - public final Symbol OBJECT_NE; - public final Symbol OBJECT_CLONE; - public final Symbol OBJECT_SYNCHRONIZED; - - /** Some java.lang.String methods */ - public final Symbol STRING_PLUS; - - /** Some java.lang.Throwable methods */ - public final Symbol THROWABLE_THROW; - - //######################################################################## - // Public Fields & Methods - Scala value class methods - - /** Some scala.Boolean methods */ - private Symbol BOOLEAN_OR; - private Symbol BOOLEAN_AND; - private Symbol BOOLEAN_NOT; - - public Symbol BOOLEAN_OR() { - if (BOOLEAN_OR == null) - BOOLEAN_OR = loadTerm(BOOLEAN_CLASS, Names.BARBAR); - return BOOLEAN_OR; - } - public Symbol BOOLEAN_AND() { - if (BOOLEAN_AND == null) - BOOLEAN_AND = loadTerm(BOOLEAN_CLASS, Names.AMPAMP); - return BOOLEAN_AND; - } - public Symbol BOOLEAN_NOT() { - if (BOOLEAN_NOT == null) - BOOLEAN_NOT = loadTerm(BOOLEAN_CLASS, Names.BANG); - return BOOLEAN_NOT; - } - - //######################################################################## - // Public Fields & Methods - Scala reference class methods - - /** Some scala.ScalaObject methods */ - private Symbol SCALAOBJECT_TAG; - - public Symbol SCALAOBJECT_TAG() { - if (SCALAOBJECT_TAG == null) - SCALAOBJECT_TAG = loadTerm(SCALAOBJECT_CLASS, Names.tag); - return SCALAOBJECT_TAG; - } - - private Symbol SCALAOBJECT_GETTYPE; - - public Symbol SCALAOBJECT_GETTYPE() { - if (SCALAOBJECT_GETTYPE == null) - SCALAOBJECT_GETTYPE = loadTerm(SCALAOBJECT_CLASS, Names.getScalaType); - return SCALAOBJECT_GETTYPE; - } - - /** Some scala.Ref methods */ - private Symbol REF_ELEM; - - public Symbol REF_ELEM() { - if (REF_ELEM == null) - REF_ELEM = loadTerm(REF_CLASS, Names.elem); - return REF_ELEM; - } - - /** Some scala.TupleX methods */ - private final Symbol[][] TUPLE_FIELD = new Symbol[TUPLE_COUNT][]; - - public Symbol TUPLE_FIELD(int arity, int index) { - assert 0 < arity && arity < TUPLE_COUNT: arity; - assert 0 < index && index <= arity: arity + " - " + index; - if (TUPLE_FIELD[arity][index - 1] == null) - TUPLE_FIELD[arity][index - 1] = loadTerm(TUPLE_CLASS[arity],Names.TUPLE_FIELD(index)); - return TUPLE_FIELD[arity][index - 1]; - } - - /** Some scala.FunctionX methods */ - private final Symbol[] FUNCTION_APPLY = new Symbol[FUNCTION_COUNT]; - - public Symbol FUNCTION_APPLY(int arity) { - assert 0 <= arity && arity < FUNCTION_COUNT: arity; - if (FUNCTION_APPLY[arity] == null) - FUNCTION_APPLY[arity] = loadTerm(FUNCTION_CLASS[arity],Names.apply); - return FUNCTION_APPLY[arity]; - } - - /** Some scala.PartialFunction methods */ - private Symbol PARTIALFUNCTION_ISDEFINEDAT; - - public Symbol PARTIALFUNCTION_ISDEFINEDAT() { - if (PARTIALFUNCTION_ISDEFINEDAT == null) - PARTIALFUNCTION_ISDEFINEDAT = loadTerm(PARTIALFUNCTION_CLASS, Names.isDefinedAt); - return PARTIALFUNCTION_ISDEFINEDAT; - } - - /** Some scala.Iterable methods */ - private Symbol ITERABLE_ELEMENTS; - - public Symbol ITERABLE_ELEMENTS() { - if (ITERABLE_ELEMENTS == null) - ITERABLE_ELEMENTS = loadTerm(ITERABLE_CLASS, Names.elements); - return ITERABLE_ELEMENTS; - } - - /** Some scala.Iterator methods */ - private Symbol ITERATOR_NEXT; - private Symbol ITERATOR_HASNEXT; - - public Symbol ITERATOR_NEXT() { - if (ITERATOR_NEXT == null) - ITERATOR_NEXT = loadTerm(ITERATOR_CLASS, Names.next); - return ITERATOR_NEXT; - } - public Symbol ITERATOR_HASNEXT() { - if (ITERATOR_HASNEXT == null) - ITERATOR_HASNEXT = loadTerm(ITERATOR_CLASS, Names.hasNext); - return ITERATOR_HASNEXT; - } - - /** Some scala.Seq methods */ - private Symbol SEQ_LENGTH; - - public Symbol SEQ_LENGTH() { - if (SEQ_LENGTH == null) - SEQ_LENGTH = loadTerm(SEQ_CLASS, Names.length); - return SEQ_LENGTH; - } - - /** Some scala.List methods */ - private Symbol LIST_ISEMPTY; - private Symbol LIST_HEAD; - private Symbol LIST_TAIL; - - public Symbol LIST_ISEMPTY() { - if (LIST_ISEMPTY == null) - LIST_ISEMPTY = loadTerm(LIST_CLASS, Names.isEmpty); - return LIST_ISEMPTY; - } - public Symbol LIST_HEAD() { - if (LIST_HEAD == null) - LIST_HEAD = loadTerm(LIST_CLASS, Names.head); - return LIST_HEAD; - } - public Symbol LIST_TAIL() { - if (LIST_TAIL == null) - LIST_TAIL = loadTerm(LIST_CLASS, Names.tail); - return LIST_TAIL; - } - - /** The scala.Array class */ - private Symbol ARRAY_LENGTH; - private Symbol ARRAY_GET; - private Symbol ARRAY_SET; - - public Symbol ARRAY_LENGTH() { - if (ARRAY_LENGTH == null) - ARRAY_LENGTH = loadTerm(ARRAY_CLASS, Names.length); - return ARRAY_LENGTH; - } - - public Symbol ARRAY_GET() { - if (ARRAY_GET == null) - ARRAY_GET = loadTerm(ARRAY_CLASS, Names.apply, new Type[]{int_TYPE()}); - return ARRAY_GET; - } - - public Symbol ARRAY_SET() { - if (ARRAY_SET == null) - ARRAY_SET = loadTerm(ARRAY_CLASS, Names.update); - return ARRAY_SET; - } - - /** Some scala.Predef methods */ - private Symbol PREDEF_ARRAY; - - public Symbol PREDEF_ARRAY() { - if (PREDEF_ARRAY == null) - PREDEF_ARRAY = PREDEF.lookup(Names.Array).firstAlternative(); - return PREDEF_ARRAY; - } - - /** Some scala.Console methods */ - private Symbol CONSOLE_PRINT; - - public Symbol CONSOLE_PRINT() { - if (CONSOLE_PRINT == null) - CONSOLE_PRINT = loadTerm(CONSOLE, Names.print); - return CONSOLE_PRINT; - } - - /** Some scala.MatchError methods */ - private Symbol MATCHERROR_FAIL; - - public Symbol MATCHERROR_FAIL() { - if (MATCHERROR_FAIL == null) - MATCHERROR_FAIL = loadTerm(MATCHERROR, Names.fail); - return MATCHERROR_FAIL; - } - - private Symbol MATCHERROR_REPORT; - - public Symbol MATCHERROR_REPORT() { - if (MATCHERROR_REPORT == null) - MATCHERROR_REPORT = loadTerm(MATCHERROR, Names.report); - return MATCHERROR_REPORT; - } - - /** The scala.Type class (and subclasses) */ - private Symbol TYPE_DEFAULTVALUE; - public Symbol TYPE_DEFAULTVALUE() { - if (TYPE_DEFAULTVALUE == null) - TYPE_DEFAULTVALUE = loadTerm(TYPE_CLASS, Names.defaultValue); - return TYPE_DEFAULTVALUE; - } - - private Symbol TYPE_NEWARRAY; - public Symbol TYPE_NEWARRAY() { - if (TYPE_NEWARRAY == null) - TYPE_NEWARRAY = loadTerm(TYPE_CLASS, Names.newArray); - return TYPE_NEWARRAY; - } - - private Symbol TYPE_ISINSTANCE; - public Symbol TYPE_ISINSTANCE() { - if (TYPE_ISINSTANCE == null) - TYPE_ISINSTANCE = loadTerm(TYPE_CLASS, Names.isInstance); - assert TYPE_ISINSTANCE != Symbol.NONE; - return TYPE_ISINSTANCE; - } - - private Symbol TYPE_CAST; - public Symbol TYPE_CAST() { - if (TYPE_CAST == null) - TYPE_CAST = loadTerm(TYPE_CLASS, Names.cast); - return TYPE_CAST; - } - - private Symbol RTT_DOUBLE; - public Symbol RTT_DOUBLE() { - if (RTT_DOUBLE == null) - RTT_DOUBLE = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Double); - return RTT_DOUBLE; - } - - private Symbol RTT_FLOAT; - public Symbol RTT_FLOAT() { - if (RTT_FLOAT == null) - RTT_FLOAT = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Float); - return RTT_FLOAT; - } - - private Symbol RTT_LONG; - public Symbol RTT_LONG() { - if (RTT_LONG == null) - RTT_LONG = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Long); - return RTT_LONG; - } - - private Symbol RTT_INT; - public Symbol RTT_INT() { - if (RTT_INT == null) - RTT_INT = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Int); - return RTT_INT; - } - - private Symbol RTT_SHORT; - public Symbol RTT_SHORT() { - if (RTT_SHORT == null) - RTT_SHORT = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Short); - return RTT_SHORT; - } - - private Symbol RTT_CHAR; - public Symbol RTT_CHAR() { - if (RTT_CHAR == null) - RTT_CHAR = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Char); - return RTT_CHAR; - } - - private Symbol RTT_BYTE; - public Symbol RTT_BYTE() { - if (RTT_BYTE == null) - RTT_BYTE = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Byte); - return RTT_BYTE; - } - - private Symbol RTT_BOOLEAN; - public Symbol RTT_BOOLEAN() { - if (RTT_BOOLEAN == null) - RTT_BOOLEAN = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Boolean); - return RTT_BOOLEAN; - } - - private Symbol RTT_UNIT; - public Symbol RTT_UNIT() { - if (RTT_UNIT == null) - RTT_UNIT = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Unit); - return RTT_UNIT; - } - - private Symbol RTT_ANY; - public Symbol RTT_ANY() { - if (RTT_ANY == null) - RTT_ANY = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Any); - return RTT_ANY; - } - - private Symbol RTT_ANYVAL; - public Symbol RTT_ANYVAL() { - if (RTT_ANYVAL == null) - RTT_ANYVAL = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.AnyVal); - return RTT_ANYVAL; - } - - private Symbol RTT_ALLREF; - public Symbol RTT_ALLREF() { - if (RTT_ALLREF == null) - RTT_ALLREF = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.AllRef); - return RTT_ALLREF; - } - - private Symbol RTT_ALL; - public Symbol RTT_ALL() { - if (RTT_ALL == null) - RTT_ALL = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.All); - return RTT_ALL; - } - - private Symbol TYPECONSTRUCTOR_GETINSTANTIATION; - public Symbol TYPECONSTRUCTOR_GETINSTANTIATION() { - if (TYPECONSTRUCTOR_GETINSTANTIATION == null) { - TYPECONSTRUCTOR_GETINSTANTIATION = - loadTerm(TYPECONSTRUCTOR_CLASS, Names.getInstantiation); - } - return TYPECONSTRUCTOR_GETINSTANTIATION; - } - - private Symbol TYPECONSTRUCTOR_INSTANTIATE; - public Symbol TYPECONSTRUCTOR_INSTANTIATE() { - if (TYPECONSTRUCTOR_INSTANTIATE == null) - TYPECONSTRUCTOR_INSTANTIATE = - loadTerm(TYPECONSTRUCTOR_CLASS, Names.instantiate); - return TYPECONSTRUCTOR_INSTANTIATE; - } - - private Symbol TYPECONSTRUCTOR_FUNCTIONOUTER; - public Symbol TYPECONSTRUCTOR_FUNCTIONOUTER() { - if (TYPECONSTRUCTOR_FUNCTIONOUTER == null) - TYPECONSTRUCTOR_FUNCTIONOUTER = - loadTerm(TYPECONSTRUCTOR_CLASS.linkedModule().moduleClass(), Names.functionOuter); - return TYPECONSTRUCTOR_FUNCTIONOUTER; - } - - private Symbol CLASSTYPE_ISNONTRIVIALINSTANCE; - public Symbol CLASSTYPE_ISNONTRIVIALINSTANCE() { - if (CLASSTYPE_ISNONTRIVIALINSTANCE == null) - CLASSTYPE_ISNONTRIVIALINSTANCE = - loadTerm(CLASSTYPE_CLASS, Names.isNonTrivialInstance); - return CLASSTYPE_ISNONTRIVIALINSTANCE; - } - - private Symbol SCALACLASSTYPE_SETPARENTS; - public Symbol SCALACLASSTYPE_SETPARENTS() { - if (SCALACLASSTYPE_SETPARENTS == null) - SCALACLASSTYPE_SETPARENTS = - loadTerm(SCALACLASSTYPE_CLASS, Names.setParents); - return SCALACLASSTYPE_SETPARENTS; - } - - private Symbol SCALACLASSTYPE_EMPTYARRAY; - public Symbol SCALACLASSTYPE_EMPTYARRAY() { - if (SCALACLASSTYPE_EMPTYARRAY == null) - SCALACLASSTYPE_EMPTYARRAY = - loadTerm(SCALACLASSTYPE_CLASS.linkedModule().moduleClass(), - Names.emptyArray); - return SCALACLASSTYPE_EMPTYARRAY; - } - - private Symbol JAVACLASSTYPE_JAVACLASSTYPE; - public Symbol JAVACLASSTYPE_JAVACLASSTYPE() { - if (JAVACLASSTYPE_JAVACLASSTYPE == null) - JAVACLASSTYPE_JAVACLASSTYPE = - loadTerm(JAVACLASSTYPE_CLASS.linkedModule().moduleClass(), - Names.javaClassType); - return JAVACLASSTYPE_JAVACLASSTYPE; - } - - private Symbol JAVACLASSTYPE_JAVAARRAYTYPE; - public Symbol JAVACLASSTYPE_JAVAARRAYTYPE() { - if (JAVACLASSTYPE_JAVAARRAYTYPE == null) - JAVACLASSTYPE_JAVAARRAYTYPE = - loadTerm(JAVACLASSTYPE_CLASS.linkedModule().moduleClass(), - Names.javaArrayType); - return JAVACLASSTYPE_JAVAARRAYTYPE; - } - - private Symbol JAVAREFARRAYTYPE_JAVAREFARRAYTYPE; - public Symbol JAVAREFARRAYTYPE_JAVAREFARRAYTYPE() { - if (JAVAREFARRAYTYPE_JAVAREFARRAYTYPE == null) - JAVAREFARRAYTYPE_JAVAREFARRAYTYPE = - loadTerm(JAVAREFARRAYTYPE_CLASS.linkedModule().moduleClass(), - Names.javaRefArrayType); - return JAVAREFARRAYTYPE_JAVAREFARRAYTYPE; - } - - // MSIL delegate types - public final Symbol DELEGATE_CLASS; - public final Type DELEGATE_TYPE() { - return DELEGATE_CLASS != null ? DELEGATE_CLASS.staticType() : null; - } - - //######################################################################## - // Public Fields - Global values - - /** The universal pattern */ - public final Symbol PATTERN_WILDCARD; - - //######################################################################## - // Private Fields - Symbol - - private final Symbol void_TYPE; - private final Symbol boolean_TYPE; - private final Symbol byte_TYPE; - private final Symbol short_TYPE; - private final Symbol char_TYPE; - private final Symbol int_TYPE; - private final Symbol long_TYPE; - private final Symbol float_TYPE; - private final Symbol double_TYPE; - private final Symbol array_TYPE; - - //######################################################################## - // Public Constructor - - /** Initializes this instance. */ - public Definitions(Global global) { - // make definitions accessible earlier to other components - global.definitions = this; - // create attributed tree typer - atyper = new ATreeTyper(global, this); - - final boolean forMSIL = global.target == Global.TARGET_MSIL; - - // the root class - ROOT_CLASS = ClassSymbol.newRootClass(global); - - // the java, java.lang and scala packages - JAVALANG = getModule(forMSIL ? "System" : "java.lang"); - SCALA = getModule("scala"); - - // the top and bottom classes - Symbol SCALA_CLASS = SCALA.moduleClass(); - ANY_CLASS = newClass(SCALA_CLASS, Names.Any, 0); - ANYVAL_CLASS = getClass("scala.AnyVal"); - ANYREF_CLASS = newAlias(SCALA_CLASS, Names.AnyRef, 0); - ALLREF_CLASS = newClass(SCALA_CLASS, Names.AllRef, Modifiers.ABSTRACT | Modifiers.FINAL); - ALL_CLASS = newClass(SCALA_CLASS, Names.All, Modifiers.ABSTRACT | Modifiers.FINAL); - - // the java classes - OBJECT_CLASS = getClass(forMSIL ? "System.Object" : "java.lang.Object"); - STRING_CLASS = getClass(forMSIL ? "System.String" : "java.lang.String"); - THROWABLE_CLASS = - getClass(forMSIL ? "System.Exception" : "java.lang.Throwable"); - // .NET delegate class - DELEGATE_CLASS = forMSIL ? getClass("System.MulticastDelegate") : null; - - // the scala value classes - UNIT_CLASS = getClass("scala.Unit"); - BOOLEAN_CLASS = getClass("scala.Boolean"); - BYTE_CLASS = getClass("scala.Byte"); - SHORT_CLASS = getClass("scala.Short"); - CHAR_CLASS = getClass("scala.Char"); - INT_CLASS = getClass("scala.Int"); - LONG_CLASS = getClass("scala.Long"); - FLOAT_CLASS = getClass("scala.Float"); - DOUBLE_CLASS = getClass("scala.Double"); - - // the scala reference classes - SCALAOBJECT_CLASS = getClass("scala.ScalaObject"); - ATTRIBUTE_CLASS = getClass("scala.Attribute"); - REF_CLASS = getClass("scala.Ref"); - for (int i = 1; i < TUPLE_COUNT; i++) { - TUPLE_CLASS[i] = getClass("scala.Tuple" + i); - TUPLE_FIELD[i] = new Symbol[i]; - } - for (int i = 0; i < FUNCTION_COUNT; i++) - FUNCTION_CLASS[i] = getClass("scala.Function" + i); - PARTIALFUNCTION_CLASS = getClass("scala.PartialFunction"); - ITERABLE_CLASS = getClass("scala.Iterable"); - ITERATOR_CLASS = getClass("scala.Iterator"); - SEQ_CLASS = getClass("scala.Seq"); - LIST_CLASS = getClass("scala.List"); - ARRAY_CLASS = getClass("scala.Array"); - TYPE_CLASS = getJVMClass("scala.Type"); - - CLASSTYPE_CLASS = getJVMClass("scala.runtime.types.ClassType"); - JAVACLASSTYPE_CLASS = getJVMClass("scala.runtime.types.JavaClassType"); - JAVAREFARRAYTYPE_CLASS = getJVMClass("scala.runtime.types.JavaRefArrayType"); - SCALACLASSTYPE_CLASS = getJVMClass("scala.runtime.types.ScalaClassType"); - SINGLETYPE_CLASS = getJVMClass("scala.runtime.types.SingleType"); - TYPECONSTRUCTOR_CLASS = getJVMClass("scala.runtime.types.TypeConstructor"); - COMPOUNDTYPE_CLASS = getJVMClass("scala.runtime.types.CompoundType"); - LAZYPARENTS_CLASS = getJVMClass("scala.runtime.types.LazyParents"); - - PREDEF = getModule("scala.Predef"); - CONSOLE = getModule("scala.Console"); - MATCHERROR = getModule("scala.MatchError"); - - SCALA_SERIALIZABLE_CONSTR = getClass("scala.serializable") - .primaryConstructor(); - SCALA_TRANSIENT_CONSTR = getClass("scala.transient") - .primaryConstructor(); - SCALA_VOLATILE_CONSTR = getClass("scala.volatile") - .primaryConstructor(); - SCALA_CLONEABLE_CONSTR = getClass("scala.cloneable") - .primaryConstructor(); - - // initialize generated classes and aliases - initClass(ANY_CLASS, Type.EMPTY_ARRAY); - initAlias(ANYREF_CLASS, OBJECT_TYPE()); - initClass(ALLREF_CLASS, new Type[]{ANYREF_TYPE()}); - initClass(ALL_CLASS, new Type[]{ANY_TYPE()}); - - // create type symbols - void_TYPE = newTypeMethod(Names.Unit ,UNIT_TYPE()); - boolean_TYPE = newTypeMethod(Names.Boolean,BOOLEAN_TYPE()); - byte_TYPE = newTypeMethod(Names.Byte ,BYTE_TYPE()); - short_TYPE = newTypeMethod(Names.Short ,SHORT_TYPE()); - char_TYPE = newTypeMethod(Names.Char ,CHAR_TYPE()); - int_TYPE = newTypeMethod(Names.Int ,INT_TYPE()); - long_TYPE = newTypeMethod(Names.Long ,LONG_TYPE()); - float_TYPE = newTypeMethod(Names.Float ,FLOAT_TYPE()); - double_TYPE = newTypeMethod(Names.Double ,DOUBLE_TYPE()); - array_TYPE = newTypeMethod(Names.Array ,ARRAY_TYPE(ANYREF_TYPE())); - - // add members to scala.Any - ANY_EQEQ = newMethod(ANY_CLASS,Names.EQEQ ,Modifiers.FINAL); - ANY_BANGEQ = newMethod(ANY_CLASS,Names.BANGEQ ,Modifiers.FINAL); - ANY_EQUALS = newMethod(ANY_CLASS,Names.equals ,0); - ANY_HASHCODE = newMethod(ANY_CLASS,Names.hashCode ,0); - ANY_TOSTRING = newMethod(ANY_CLASS,Names.toString ,0); - // ANY_PLUS = newMethod(ANY_CLASS,Names.PLUS ,Modifiers.FINAL); - ANY_IS = newMethod(ANY_CLASS,Names.isInstanceOf,Modifiers.FINAL); - ANY_IS_ERASED= newMethod(ANY_CLASS,Names.isInstanceOfE,Modifiers.FINAL); - ANY_AS = newMethod(ANY_CLASS,Names.asInstanceOf,Modifiers.FINAL); - ANY_AS_ERASED= newMethod(ANY_CLASS,Names.asInstanceOfE,Modifiers.FINAL); - ANY_MATCH = newMethod(ANY_CLASS,Names._match ,Modifiers.FINAL); - - initMethod(ANY_EQEQ , new Type[]{ANY_TYPE()} , boolean_TYPE()); - initMethod(ANY_BANGEQ , new Type[]{ANY_TYPE()} , boolean_TYPE()); - initMethod(ANY_EQUALS , new Type[]{ANY_TYPE()} , boolean_TYPE()); - initMethod(ANY_HASHCODE, new Type[]{} , int_TYPE()); - initMethod(ANY_TOSTRING, new Type[]{} , STRING_TYPE()); - // initMethod(ANY_PLUS , new Type[]{STRING_TYPE()}, STRING_TYPE()); - - Symbol[] ANY_IS_TPARAMS = {newTParam(ANY_IS, 0, ANY_TYPE())}; - ANY_IS.setInfo(Type.PolyType(ANY_IS_TPARAMS, boolean_TYPE())); - Symbol[] ANY_IS_ERASED_TPARAMS = - {newTParam(ANY_IS_ERASED, 0, ANY_TYPE())}; - ANY_IS_ERASED.setInfo(Type.PolyType(ANY_IS_ERASED_TPARAMS, - boolean_TYPE())); - - Symbol[] ANY_AS_TPARAMS = {newTParam(ANY_AS, 0, ANY_TYPE())}; - ANY_AS.setInfo(Type.PolyType(ANY_AS_TPARAMS,ANY_AS_TPARAMS[0].type())); - Symbol[] ANY_AS_ERASED_TPARAMS = - {newTParam(ANY_AS_ERASED, 0, ANY_TYPE())}; - ANY_AS_ERASED.setInfo(Type.PolyType(ANY_AS_ERASED_TPARAMS, - ANY_AS_ERASED_TPARAMS[0].type())); - - Symbol[] ANY_MATCH_TPARAMS = { - newTParam(ANY_MATCH, 0, ANY_TYPE()), - newTParam(ANY_MATCH, 1, ANY_TYPE())}; - Symbol[] ANY_MATCH_VPARAMS = { - newVParam(ANY_MATCH, 0, FUNCTION_TYPE( - new Type[]{ANY_MATCH_TPARAMS[0].type()}, - ANY_MATCH_TPARAMS[1].type()))}; - ANY_MATCH.setInfo( - Type.PolyType( - ANY_MATCH_TPARAMS, - Type.MethodType( - ANY_MATCH_VPARAMS, - ANY_MATCH_TPARAMS[1].type()))); - - // add members to java.lang.Object - OBJECT_EQ = - newMethod(OBJECT_CLASS, Names.eq, Modifiers.FINAL); - OBJECT_NE = - newMethod(OBJECT_CLASS, Names.ne, Modifiers.FINAL); - OBJECT_SYNCHRONIZED = - newMethod(OBJECT_CLASS, Names.synchronized_, Modifiers.FINAL); - - initMethod(OBJECT_EQ, new Type[]{ANYREF_TYPE()}, boolean_TYPE()); - initMethod(OBJECT_NE, new Type[]{ANYREF_TYPE()}, boolean_TYPE()); - Symbol OBJECT_SYNCHRONIZED_TPARAM = - newTParam(OBJECT_SYNCHRONIZED,0,ANY_TYPE()); - Symbol OBJECT_SYNCHRONIZED_VPARAM = - newVParam(OBJECT_SYNCHRONIZED,0,OBJECT_SYNCHRONIZED_TPARAM.type()); - OBJECT_SYNCHRONIZED.setInfo( - Type.PolyType( - new Symbol[] {OBJECT_SYNCHRONIZED_TPARAM}, - Type.MethodType( - new Symbol[] {OBJECT_SYNCHRONIZED_VPARAM}, - OBJECT_SYNCHRONIZED_TPARAM.type()))); - - if (forMSIL) { - OBJECT_CLONE = newMethod(OBJECT_CLASS, Names.clone, Modifiers.PROTECTED); - initMethod(OBJECT_CLONE, Type.EMPTY_ARRAY, ANYREF_TYPE()); - - Symbol WAIT0 = newMethod(OBJECT_CLASS, Names.wait, Modifiers.FINAL); - initMethod(WAIT0, Type.EMPTY_ARRAY, UNIT_TYPE()); - - Symbol WAIT1 = newMethod(OBJECT_CLASS, Names.wait, Modifiers.FINAL); - initMethod(WAIT1, new Type[]{LONG_TYPE()}, UNIT_TYPE()); - - Symbol WAIT2 = newMethod(OBJECT_CLASS, Names.wait, Modifiers.FINAL); - initMethod(WAIT2, new Type[]{LONG_TYPE(), INT_TYPE()}, UNIT_TYPE()); - - Symbol NOTIFY = - newMethod(OBJECT_CLASS, Names.notify, Modifiers.FINAL); - initMethod(NOTIFY, Type.EMPTY_ARRAY, UNIT_TYPE()); - - Symbol NOTIFY_ALL = - newMethod(OBJECT_CLASS, Names.notifyAll, Modifiers.FINAL); - initMethod(NOTIFY_ALL, Type.EMPTY_ARRAY, UNIT_TYPE()); - } else { - OBJECT_CLONE = null; - } - - // add members to java.lang.String - STRING_PLUS = newMethod(STRING_CLASS, Names.PLUS, Modifiers.FINAL); - initMethod(STRING_PLUS, new Type[]{ANY_TYPE()}, STRING_TYPE()); - - if (forMSIL) { - Symbol s = newMethod(STRING_CLASS, Name.fromString("length"), 0); - initMethod(s, Type.EMPTY_ARRAY, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("compareTo"), 0); - initMethod(s, new Type[] {STRING_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("charAt"), 0); - initMethod(s, new Type[] {INT_TYPE()}, CHAR_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("concat"), 0); - initMethod(s, new Type[] {STRING_TYPE()}, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("indexOf"), 0); - initMethod(s, new Type[] {INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("indexOf"), 0); - initMethod(s, new Type[] {INT_TYPE(), INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("indexOf"), 0); - initMethod(s, new Type[] {STRING_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("indexOf"), 0); - initMethod(s, new Type[] {STRING_TYPE(), INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("lastIndexOf"), 0); - initMethod(s, new Type[] {INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("lastIndexOf"), 0); - initMethod(s, new Type[] {INT_TYPE(), INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("lastIndexOf"), 0); - initMethod(s, new Type[] {STRING_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("lastIndexOf"), 0); - initMethod(s, new Type[] {STRING_TYPE(), INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("toLowerCase"), 0); - initMethod(s, Type.EMPTY_ARRAY, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("toUpperCase"), 0); - initMethod(s, Type.EMPTY_ARRAY, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("startsWith"), 0); - initMethod(s, new Type[]{STRING_TYPE()}, BOOLEAN_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("endsWith"), 0); - initMethod(s, new Type[]{STRING_TYPE()}, BOOLEAN_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("substring"), 0); - initMethod(s, new Type[]{INT_TYPE()}, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("substring"), 0); - initMethod(s, new Type[]{INT_TYPE(), INT_TYPE()}, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("intern"), 0); - initMethod(s, Type.EMPTY_ARRAY, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("replace"), 0); - initMethod(s, new Type[]{CHAR_TYPE(), CHAR_TYPE()}, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("toCharArray"), 0); - initMethod(s, Type.EMPTY_ARRAY, array_TYPE(CHAR_TYPE())); - } - - // add members to java.lang.Throwable - THROWABLE_THROW = - newMethod(THROWABLE_CLASS, Names.throw_, Modifiers.FINAL); - THROWABLE_THROW.setInfo(Type.PolyType(Symbol.EMPTY_ARRAY, ALL_TYPE())); - - // create global values - PATTERN_WILDCARD = Symbol.NONE.newTerm( - Position.NOPOS, 0, Names.PATTERN_WILDCARD); - PATTERN_WILDCARD.setInfo(ALL_TYPE()); - - // initialize unboxed types in class Type - Type.initializeUnboxedTypes(this); - } - - //######################################################################## - // Public Methods - - /** Returns the symbol of the module with the given fullname. */ - public Symbol getModule(String fullname) { - Scope scope = ROOT_CLASS.members(); - int i = 0; - int j = fullname.indexOf('.', i); - while (j >= 0) { - Name name = Name.fromString(fullname.substring(i, j)); - scope = scope.lookup(name).members(); - i = j + 1; - j = fullname.indexOf('.', i); - } - Name name = Name.fromString(fullname.substring(i, fullname.length())); - Symbol sym = scope.lookup(name); - if (!sym.isModule()) { - switch (sym.type()) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int k = 0; k < alts.length; k++) - if ((sym = alts[k]).isModule()) break; - } - } - return sym; - } - - /** Returns the symbol of the class with the given fullname. */ - public Symbol getClass(String fullname) { - Scope scope = ROOT_CLASS.members(); - int i = 0; - int j = fullname.indexOf('.', i); - while (j >= 0) { - Name name = Name.fromString(fullname.substring(i, j)); - scope = scope.lookup(name).members(); - i = j + 1; - j = fullname.indexOf('.', i); - } - Name name = Name.fromString(fullname.substring(i, fullname.length())); - Symbol sym = scope.lookup(name.toTypeName()); - assert sym.kind != Kinds.NONE : "no class '" + fullname + "'"; - return sym; - } - - private Symbol getJVMClass(String fullname) { - return Global.instance.target == Global.TARGET_MSIL ? null : - getClass(fullname); - } - - //######################################################################## - // Private Methods - - /** Creates a new class */ - private Symbol newClass(Symbol owner, Name name, int flags) { - name = name.toTypeName(); - Symbol clasz = owner.newClass(Position.NOPOS, flags, name); - owner.members().enter(clasz); - return clasz; - } - - /** Creates a new type alias */ - private Symbol newAlias(Symbol owner, Name name, int flags) { - name = name.toTypeName(); - Symbol alias = owner.newTypeAlias(Position.NOPOS, flags, name); - owner.members().enter(alias); - return alias; - } - - /** Creates a new method */ - private Symbol newMethod(Symbol owner, Name name, int flags) { - assert owner.isClassType(): Debug.show(owner) + " -- " + name; - Symbol term = owner.newMethod(Position.NOPOS, flags, name); - owner.members().enterOrOverload(term); - return term; - } - - /** Creates a new type parameter */ - private Symbol newTParam(Symbol owner, int index, Type bound) { - Name name = Name.fromString("T" + index).toTypeName(); - return owner.newTParam(Position.NOPOS, 0, name, bound); - } - - /** Creates a new value parameter */ - private Symbol newVParam(Symbol owner, int index, Type type) { - Name name = Name.fromString("v" + index); - return owner.newVParam(Position.NOPOS, 0, name, type); - } - - /** Creates a new type method */ - private Symbol newTypeMethod(Name name, Type type) { - Symbol symbol = ANY_CLASS.newMethod(Position.NOPOS, 0, name); - initMethod(symbol, Type.EMPTY_ARRAY, type); - return symbol; - } - - /** Initializes the given class */ - private void initClass(Symbol clasz, Type[] parents) { - clasz.setInfo(Type.compoundType(parents, new Scope(), clasz)); - clasz.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clasz.typeConstructor())); - } - - /** Initializes the given type alias */ - private void initAlias(Symbol alias, Type aliased) { - alias.setInfo(aliased); - alias.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, aliased)); - } - - /** Initializes the given method */ - private void initMethod(Symbol method, Type[] vargs, Type result) { - Symbol[] vparams = new Symbol[vargs.length]; - for (int i = 0; i < vargs.length; i++) - vparams[i] = newVParam(method, i, vargs[i]); - method.setInfo(Type.MethodType(vparams, result)); - } - - /** Returns the term member of given class with given name. */ - private Symbol loadTerm(Symbol clasz, Name name) { - Symbol sym = clasz.lookup(name); - assert sym.isTerm(): clasz+"."+name+" -> "+sym; - assert !sym.isOverloaded(): clasz+"."+name+" -> "+sym; - return sym; - } - - /** - * Returns the term member of given class with given name and - * value argument types. - */ - private Symbol loadTerm(Symbol clasz, Name name, Type[] vargs) { - Symbol sym = clasz.lookup(name); - assert sym.isTerm(): Debug.show(clasz, name, vargs, sym); - Symbol[] alts = sym.alternativeSymbols(); - for (int i = 0; i < alts.length; i++) { - switch (alts[i].type()) { - case PolyType(_, MethodType(Symbol[] vparams, _)): - if (Type.isSameAs(Symbol.type(vparams), vargs)) return alts[i]; - continue; - case MethodType(Symbol[] vparams, _): - if (Type.isSameAs(Symbol.type(vparams), vargs)) return alts[i]; - continue; - } - } - throw Debug.abort(Debug.show(clasz, name, vargs, alts)); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/EntryTags.java b/sources/scalac/symtab/EntryTags.java deleted file mode 100644 index ca6f0bd294..0000000000 --- a/sources/scalac/symtab/EntryTags.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id: EntryTags.java - -package scalac.symtab; - -public interface EntryTags { - -/*************************************************** - * Symbol table attribute format: - * Symtab = nentries_Nat {Entry} - * Entry = 1 TERMNAME len_Nat NameInfo - * | 2 TYPENAME len_Nat NameInfo - * | 3 NUMBER lenNat NumInfo - * | 4 NONEsym len_Nat - * | 5 TYPEsym len_Nat SymbolInfo lobound_Ref - * | 6 ALIASsym len_Nat SymbolInfo constrsym_Ref - * | 7 CLASSsym len_Nat SymbolInfo [modulesym_Ref] - * thistype_Ref constrsym_Ref - * | 8 VALsym len_Nat SymbolInfo [classsym_Ref] - * | 9 EXTref len_Nat name_Ref [owner_Ref] - * | 10 EXTMODCLASSref len_Nat name_Ref [owner_Ref] - * | 11 NOtpe len_Nat - * | 12 THIStpe len_Nat sym_Ref - * | 13 SINGLEtpe len_Nat type_Ref sym_Ref - * | 14 CONSTANTtpe len_Nat type_Ref constant_Ref - * | 15 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref} - * | 16 COMPOUNDtpe len_Nat - * iscompoundsym_Byte [owner_Ref] classsym_Ref {tpe_Ref} - * | 17 METHODtpe len_Nat tpe_Ref {tpe_Ref} - * | 18 POLYTtpe len_Nat tpe_Ref {sym_Ref} - * | 19 OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref} - * | 22 FLAGGEDtpe len_Nat flags_Nat tpe_Ref - * | 24 LITERALunit len_Nat - * | 25 LITERALboolean len_Nat value_Byte - * | 26 LITERALbyte len_Nat value_Long - * | 27 LITERALshort len_Nat value_Long - * | 28 LITERALchar len_Nat value_Long - * | 29 LITERALint len_Nat value_Long - * | 30 LITERALlong len_Nat value_Long - * | 31 LITERALfloat len_Nat value_Long - * | 32 LITERALdouble len_Nat value_Long - * | 33 LITERALstring len_Nat name_Ref - * | 34 LITERALnull len_Nat - * | 35 LITERALzero len_Nat - * SymbolInfo = name_Ref owner_Ref flags_Nat info_Ref - * NameInfo = <character sequence of length len_Nat in Utf8 format> - * NumInfo = <len_Nat-byte signed number in big endian format> - * Ref = Nat - * - * len is remaining length after `len'. - */ - - int TERMname = 1, - TYPEname = 2, - NONEsym = 4, - TYPEsym = 5, - ALIASsym = 6, - CLASSsym = 7, - VALsym = 8, - EXTref = 9, - EXTMODCLASSref = 10, - NOtpe = 11, - THIStpe = 12, - SINGLEtpe = 13, - CONSTANTtpe = 14, - TYPEREFtpe = 15, - COMPOUNDtpe = 16, - METHODtpe = 17, - POLYtpe = 18, - OVERLOADEDtpe = 19, - UNBOXEDtpe = 20, - UNBOXEDARRAYtpe = 21, - FLAGGEDtpe = 22, - ERRORtpe = 23, - LITERALunit = 24, - LITERALboolean = 25, - LITERALbyte = 26, - LITERALshort = 27, - LITERALchar = 28, - LITERALint = 29, - LITERALlong = 30, - LITERALfloat = 31, - LITERALdouble = 32, - LITERALstring = 33, - LITERALnull = 34, - LITERALzero = 35, - NOpre = 36; - - int firstSymTag = NONEsym, lastSymTag = VALsym; - int firstTypeTag = NOtpe, lastTypeTag = FLAGGEDtpe; - -// flag encodings - - int REPEATEDflag = 4, DEFflag = 8; -} diff --git a/sources/scalac/symtab/Kinds.java b/sources/scalac/symtab/Kinds.java deleted file mode 100644 index b99c8fa8d0..0000000000 --- a/sources/scalac/symtab/Kinds.java +++ /dev/null @@ -1,24 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - - -public interface Kinds { - - /** kind of non-existent symbol - */ - int NONE = 1; - - /** definition kinds - */ - int ALIAS = 2; - int CLASS = 3; - int TYPE = 4; - int VAL = 5; -} diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java deleted file mode 100644 index ab222e723f..0000000000 --- a/sources/scalac/symtab/Modifiers.java +++ /dev/null @@ -1,154 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - -public interface Modifiers { - - // modifiers - int DEFERRED = 0x00000001; // was `abstract' for members - int FINAL = 0x00000002; - int PRIVATE = 0x00000004; - int PROTECTED = 0x00000008; - - int SEALED = 0x00000010; - int OVERRIDE = 0x00000020; - int CASE = 0x00000040; - int ABSTRACT = 0x00000080; // abstract class, or used in conjunction - // with abstract override. - // Note difference to DEFERRED! - - int DEF = 0x00000100; // a def parameter - int REPEATED = 0x00000200; // a repeated parameter - int SYNTHETIC = 0x00000400; - int DEPRECATED = 0x00000800; - - int JAVA = 0x00001000; // symbol was defined by a Java class - int MODUL = 0x00002000; // symbol is module or class implementing a module - int MUTABLE = 0x00004000; // symbol is a mutable variable. - int VIEWBOUND = 0x00004000; // type symbol has a <% bound. - int PARAM = 0x00008000; // symbol is a (type) parameter to a method - - int INITIALIZED = 0x00010000; // symbol's definition is complete - int LOCKED = 0x00020000; // temporary flag to catch cyclic dependencies - int ACCESSED = 0x00040000; // symbol was accessed at least once - int SELECTOR = 0x00080000; // symbol was used as selector in Select - - int PACKAGE = 0x00100000; // symbol is a java package. - int STABLE = 0x00800000; // functions that are assumed to be stable - // (typically, access methods for valdefs) - - int CAPTURED = 0x01000000; // variables is accessed from - // nested function. Set by LambdaLift - int INCONSTRUCTOR = 0x01000000; // transient flag for Analyzer - int PARAMACCESSOR = 0x02000000; // for methods: is an access method for a val parameter - // for parameters: is a val parameter - int CLOSURELOCK = PARAMACCESSOR; - // secondary meaning: a lock to test that closures of type - // symbols are non-cyclic. - - int ACCESSOR = 0x04000000; // function is an access function for a - // value or variable - int BRIDGE = 0x08000000; // function is a bridge method. - int LIFTED = BRIDGE; // transient flag for lambdalift - int ALTERNATIVE = BRIDGE; // transient flag for pickle/unpickle - int SNDTIME = BRIDGE; // debug - - int INTERFACE = 0x10000000; // symbol is a Java interface - int TRAIT = 0x20000000; // symbol is a Trait - - int COVARIANT = 0x40000000; // symbol is a covariant type variable - int CONTRAVARIANT = 0x80000000; // symbol is a contravariant type variable - - // masks - int SOURCEFLAGS = 0x00000077 | DEF | REPEATED | MODUL | MUTABLE | PACKAGE | PARAM | TRAIT | COVARIANT | CONTRAVARIANT; // these modifiers can be set in source programs. - int ACCESSFLAGS = PRIVATE | PROTECTED; - int VARIANCES = COVARIANT | CONTRAVARIANT; - int CONSTRFLAGS = CASE | JAVA; - /** Module flags inherited by their module-class */ - int MODULE2CLASSFLAGS = ACCESSFLAGS | DEPRECATED | SYNTHETIC | JAVA | PACKAGE | CASE; - - public static class Helper { - - public static boolean isAbstract(int flags) { - // todo: ABSTRACT and DEFERRED should be separated. - return (flags & DEFERRED) != 0 || - (flags & (ABSTRACT | OVERRIDE)) == ABSTRACT; - } - - public static boolean isFinal(int flags) { - return (flags & FINAL) != 0; - } - - public static boolean isPrivate(int flags) { - return (flags & PRIVATE) != 0; - } - - public static boolean isProtected(int flags) { - return (flags & PROTECTED) != 0; - } - - public static boolean isSealed(int flags) { - return (flags & SEALED) != 0; - } - - public static boolean isOverride(int flags) { - return (flags & OVERRIDE) != 0; - } - - public static boolean isCase(int flags) { - return (flags & CASE) != 0; - } - - public static boolean isCaseAccessor(int flags) { - return (flags & PARAMACCESSOR) != 0; - } - - public static boolean isInterface(int flags) { - return (flags & INTERFACE) != 0; - } - - public static boolean isDef(int flags) { - return (flags & DEF) != 0; - } - - public static boolean isModClass(int flags) { - return (flags & MODUL) != 0; - } - - public static boolean isJava(int flags) { - return (flags & JAVA) != 0; - } - - public static boolean isNoVal(int flags) { - return (flags & PACKAGE) != 0; - } - - public static String toString(int flags) { - StringBuffer buffer = new StringBuffer(); - toString(buffer, flags); - return buffer.toString(); - } - - public static void toString(StringBuffer buffer, int flags) { - //buffer.append(flags).append(": ");//debug - int marker = buffer.length(); - if (isPrivate(flags)) buffer.append("private "); - if (isProtected(flags)) buffer.append("protected "); - if (isAbstract(flags)) buffer.append("abstract "); - if (isFinal(flags)) buffer.append("final "); - if (isSealed(flags)) buffer.append("sealed "); - if (isInterface(flags)) buffer.append("interface "); - if (isCase(flags)) buffer.append("case "); - if (isDef(flags)) buffer.append("def "); - if (isOverride(flags)) buffer.append("override "); - int length = buffer.length(); - buffer.setLength(length - (length == marker ? 0 : 1)); - } - } -} diff --git a/sources/scalac/symtab/Scope.java b/sources/scalac/symtab/Scope.java deleted file mode 100644 index 7206a9ca02..0000000000 --- a/sources/scalac/symtab/Scope.java +++ /dev/null @@ -1,332 +0,0 @@ - /* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - -import scalac.util.*; -import scalac.ApplicationError; - -public class Scope { - - public abstract static class SymbolIterator { - public abstract boolean hasNext(); - public abstract Symbol next(); - } - - public static class Entry { - - /** the absent entry - */ - public static final Entry NONE = new Entry(); - - /** the symbol of the entry (this is the symbol containing the name) - */ - public Symbol sym; - - /** the next entry in the hash bucket - */ - public Entry tail; - - /** the next entry in this scope - */ - private Entry next; - - /** The owner of the entry; - */ - public final Scope owner; - - public Entry(Symbol sym, Scope owner) { - this.sym = sym; - this.owner = owner; - this.next = owner.elems; - if (sym == null) throw new ApplicationError(); - owner.elems = this; - } - - private Entry() { - this.sym = Symbol.NONE; - this.owner = null; - } - - public Entry setSymbol(Symbol sym) { - this.sym = sym; - owner.elemsCache = null; - return this; - } - - public int hashCode() { - return sym.name.index; - } - - public String toString() { - return sym.toString(); - } - } - - /** all elements of this scope - */ - private Entry elems; - - /** the hash table - */ - private Entry[] hashtable; - - /** a cache for all elements, to be used by symbol iterator. - */ - private Symbol[] elemsCache = null; - - public Symbol[] getElemsCache() { - return elemsCache; - } - - /** size and mask of hash tables - * todo: make hashtables grow? - */ - private final int HASHSIZE = 0x80; - private final int HASHMASK = 0x7f; - - /** the threshold number of entries from which a hashtable is constructed. - */ - private final int MIN_HASH = 6; - - /** construct a new name space - */ - public Scope() { - this.elems = Entry.NONE; - } - - public Scope(Entry elems) { - this.elems = elems; - if (size() >= MIN_HASH) createHash(); - } - - public Scope(Scope base) { - this.elems = base.elems; - if (base.hashtable != null) { - this.hashtable = new Entry[HASHSIZE]; - for (int i = 0; i < HASHSIZE; i++) - hashtable[i] = base.hashtable[i]; - } - } - - public Scope(Symbol[] members) { - this(); - for (int i = 0; i < members.length; i++) - enter(members[i]); - } - - /** Returns a new scope with the same content as this one. */ - public Scope cloneScope() { - int size = 0; - Scope clone = new Scope(); - for (Entry e = elems; e != Entry.NONE; e = e.next, size++) - new Entry(e.sym, clone); - if (size >= MIN_HASH) clone.createHash(); - return clone; - } - - /** is the scope empty? - */ - public boolean isEmpty() { - return elems == Entry.NONE; - } - - /** the number of entries in this scope - */ - int size() { - int s = 0; - for (Entry e = elems; e != Entry.NONE; e = e.next) s++; - return s; - } - - public Scope enter(Entry e) { - assert this != Scope.EMPTY: Debug.show(e.sym); - elems = e; - elemsCache = null; - if (hashtable != null) { - int i = e.sym.name.index & HASHMASK; - elems.tail = hashtable[i]; - hashtable[i] = elems; - } else if (size() >= MIN_HASH) { - createHash(); - } - return this; - } - - /** enter a symbol - */ - public Scope enter(Symbol sym) { - // assert !sym.isConstructor(); - return enter(new Entry(sym, this)); - } - - public final Scope enterNoHide(Symbol sym) { - assert lookupEntry(sym.name) == Entry.NONE: - sym + " hides " + lookup(sym.name); - return enter(sym); - } - - public Scope enterOrOverload(Symbol sym) { - Entry e = lookupEntry(sym.name); - if (e.owner == this/* && (sym.flags & Modifiers.PRIVATE) == 0*/) { - e.setSymbol(e.sym.overloadWith(sym)); - return this; - } else { - return enter(sym); - } - } - - private void createHash() { - hashtable = new Entry[HASHSIZE]; - for (int i = 0; i < HASHSIZE; i++) - hashtable[i] = Entry.NONE; - enterInHash(elems); - } - - private void enterInHash(Entry e) { - if (e != Entry.NONE) { - enterInHash(e.next); - int i = e.sym.name.index & HASHMASK; - e.tail = hashtable[i]; - hashtable[i] = e; - } - } - - /** remove entry - */ - public void unlink(Entry e) { - if (elems == e) { - elems = e.next; - } else { - Entry e1 = elems; - while (e1.next != e) e1 = e1.next; - e1.next = e.next; - } - if (hashtable != null) { - Entry e1 = hashtable[e.sym.name.index & HASHMASK]; - if (e1 == e) { - hashtable[e.sym.name.index & HASHMASK] = e.tail; - } else { - while (e1.tail != e) e1 = e1.tail; - e1.tail = e.tail; - } - } - elemsCache = null; - } - - public boolean contains(Symbol sym) { - Entry e = lookupEntry(sym.name); - if (e.sym == sym) return true; - switch (e.sym.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i] == sym) return true; - } - return false; - } - - /** lookup a symbol - */ - public Symbol lookup(Name name) { - return lookupEntry(name).sym; - } - - /** lookup a symbol entry. - */ - public Entry lookupEntry(Name name) { - Entry e; - if (hashtable != null) { - e = hashtable[name.index & HASHMASK]; - while (e != Entry.NONE && e.sym.name != name) e = e.tail; - } else { - e = elems; - while (e != Entry.NONE && e.sym.name != name) e = e.next; - } - return e; - } - - /** return all symbols as an array, - * in the order they were entered in this scope. - */ - public Symbol[] elements() { - if (elemsCache == null) { - int s = size(); - elemsCache = new Symbol[s]; - for (Entry e = elems; e != Entry.NONE; e = e.next) - elemsCache[--s] = e.sym; - } - return elemsCache; - } - - class MySymbolIterator extends SymbolIterator { - private Symbol[] alternatives = Symbol.EMPTY_ARRAY; - private int altindex = 0; - private int elemindex = 0; - - public MySymbolIterator() { - elements(); - } - - public boolean hasNext() { - return altindex < alternatives.length || - elemindex < elemsCache.length; - } - - public Symbol next() { - if (altindex < alternatives.length) - return alternatives[altindex++]; - else { - Symbol sym = elemsCache[elemindex++]; - switch (sym.type()) { - case OverloadedType(Symbol[] alts, _): - alternatives = alts; - altindex = 0; - return next(); - default: - return sym; - } - } - } - } - - /** return all symbols as an iterator, - * in the order they were entered in this scope. - */ - public SymbolIterator iterator() { - return new MySymbolIterator(); - } - - - public String toString() { - return new SymbolTablePrinter().printScope(this).toString(); - } - - public static Scope EMPTY = new Scope(); -} - -public class ErrorScope extends Scope { - - private final Symbol owner; - - public ErrorScope(Symbol owner) { - this.owner = owner; - } - - public Entry lookupEntry(Name name) { - Entry entry = super.lookupEntry(name); - if (entry.sym.isNone()) { - Symbol symbol = name.isTermName() - ? owner.newErrorValue(name) - : owner.newErrorClass(name); - enter(symbol); - entry = super.lookupEntry(name); - } - return entry; - } - -} diff --git a/sources/scalac/symtab/SourceCompleter.java b/sources/scalac/symtab/SourceCompleter.java deleted file mode 100644 index 73596724bd..0000000000 --- a/sources/scalac/symtab/SourceCompleter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -import scalac.Global; -import scalac.symtab.Symbol; - -/** This class implements a SymbolLoader that reads a source file. */ -public class SourceCompleter extends SymbolLoader { - - //######################################################################## - // Private Fields - - /** The source file to read */ - private final AbstractFile file; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with the specified source file. */ - public SourceCompleter(Global global, AbstractFile file) { - super(global); - this.file = file; - } - - //######################################################################## - // Protected Methods - - /** Completes the specified symbol by reading the source file. */ - protected String doComplete(Symbol root) throws IOException { - global.compileLate(global.getSourceFile(file), false); - return "source file '" + file + "'"; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymSet.java b/sources/scalac/symtab/SymSet.java deleted file mode 100644 index 0f91985386..0000000000 --- a/sources/scalac/symtab/SymSet.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -/** Sets of symbols, implemented as binary trees. - */ -public class SymSet { - private SymSet l, r; - private Symbol sym; - - public SymSet() {} - - private SymSet(Symbol sym, SymSet l, SymSet r) { - this.sym = sym; this.l = l; this.r = r; - } - - /** Union of this set and `{sym}'. - */ - public SymSet incl(Symbol sym) { - if (this == EMPTY) { - return new SymSet(sym, EMPTY, EMPTY); - } else if (sym == this.sym) { - return this; - } else if (less(sym, this.sym)) { - return new SymSet(this.sym, l.incl(sym), r); - } else { - assert less(this.sym, sym); - return new SymSet(this.sym, l, r.incl(sym)); - } - } - - /** Remove the element <code>sym</code> from the symbol set - */ - public SymSet excl(Symbol sym) { - if (sym == this.sym) { - if (l == EMPTY) return r; - if (r == EMPTY) return l; - SymSet m = r; - if (m.l != EMPTY) { - SymSet p; - do { - p = m; - m = m.l; - } while (m.l != EMPTY); - p.l = m.r; - m.r = r; - } - m.l = l; - return m; - } else if (less(sym, this.sym)) { - return new SymSet(this.sym, l.excl(sym), r); - } else { - assert less(this.sym, sym); - return new SymSet(this.sym, l, r.excl(sym)); - } - } - - /** Is `sym' an element of this set? - */ - public boolean contains(Symbol sym) { - if (this == EMPTY) { - return false; - } else if (sym == this.sym) { - return true; - } else if (less(sym, this.sym)) { - return l.contains(sym); - } else { - assert less(this.sym, sym); - return r.contains(sym); - } - } - - /** The number of elements in ths set. - */ - public int size() { - if (this == EMPTY) { - return 0; - } else { - return 1 + l.size() + r.size(); - } - } - - /** Copy elements of this set into `ss', starting at index `from'. - * Return index one past last element copied. - */ - public int copyToArray(Symbol[] ss, int from) { - if (this == EMPTY) { - return from; - } else { - from = l.copyToArray(ss, from); - ss[from] = sym; - return r.copyToArray(ss, from + 1); - } - } - - /** Return all elements of this set as an array. - */ - public Symbol[] toArray() { - int s = size(); - if (s == 0) return Symbol.EMPTY_ARRAY; - Symbol[] ss = new Symbol[s]; - copyToArray(ss, 0); - return ss; - } - - /** The empty set. - */ - public final static SymSet EMPTY = new SymSet(); - - private boolean less(Symbol s1, Symbol s2) { - return s1.isLess(s2); - } -} diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java deleted file mode 100644 index ad3710ff82..0000000000 --- a/sources/scalac/symtab/Symbol.java +++ /dev/null @@ -1,2573 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -//todo check significance of JAVA flag. - -package scalac.symtab; - -import scala.tools.util.AbstractFile; -import scala.tools.util.Position; - -import scalac.ApplicationError; -import scalac.CompilationUnit; -import scalac.Global; -import scalac.Phase; -import scalac.framework.History; -import scalac.util.ArrayApply; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.NameTransformer; - - -public abstract class Symbol implements Modifiers, Kinds { - - /** An empty symbol array */ - public static final Symbol[] EMPTY_ARRAY = new Symbol[0]; - - /** An empty array of symbol arrays */ - public static final Symbol[][] EMPTY_ARRAY_ARRAY = new Symbol[0][]; - - /** The absent symbol */ - public static final Symbol NONE = new NoSymbol(); - -// Attribues ------------------------------------------------------------- - - public static final int IS_ROOT = 0x00000001; - public static final int IS_ANONYMOUS = 0x00000002; - public static final int IS_LABEL = 0x00000010; - public static final int IS_CONSTRUCTOR = 0x00000020; - public static final int IS_ACCESSMETHOD = 0x00000100; - public static final int IS_STATIC = 0x00000200; - public static final int IS_ERROR = 0x10000000; - public static final int IS_THISTYPE = 0x20000000; - public static final int IS_LOCALDUMMY = 0x40000000; - public static final int IS_COMPOUND = 0x80000000; - -// Fields ------------------------------------------------------------- - - /** The unique identifier generator */ - private static int ids; - - /** The kind of the symbol */ - public int kind; - - /** The position of the symbol */ - public int pos; - - /** The name of the symbol */ - public Name name; - - /** The modifiers of the symbol */ - public int flags; - - /** The owner of the symbol */ - private Symbol owner; - - /** The infos of the symbol */ - private TypeIntervalList infos; - - /** The attributes of the symbol */ - private final int attrs; - - /** The unique identifier */ - public final int id; - - -// Constructors ----------------------------------------------------------- - - /** Generic symbol constructor */ - public Symbol(int kind, Symbol owner, int pos, int flags, Name name, int attrs) { - this.kind = kind; - this.pos = pos; - this.name = name; - this.owner = owner == null ? this : owner; - this.flags = flags & ~(INITIALIZED | LOCKED); // safety first - this.attrs = attrs; - this.id = ids++; - } - -// Factories -------------------------------------------------------------- - - /** Creates a new term owned by this symbol. */ - public final Symbol newTerm(int pos, int flags, Name name) { - return newTerm(pos, flags, name, 0); - } - - /** Creates a new constructor of this symbol. */ - public final Symbol newConstructor(int pos, int flags) { - assert isType(): Debug.show(this); - return new ConstructorSymbol(this, pos, flags); - } - - /** Creates a new method owned by this symbol. */ - public final Symbol newMethod(int pos, int flags, Name name) { - assert isClass(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new static method owned by this symbol. */ - public final Symbol newStaticMethod(int pos, int flags, Name name) { - assert isClass(): Debug.show(this); - return newTerm(pos, flags, name, IS_STATIC); - } - - /** Creates a new access method owned by this symbol. */ - public final Symbol newAccessMethod(int pos, Name name) { - assert isClass(): Debug.show(this); - int flags = PRIVATE | FINAL | SYNTHETIC; - return newTerm(pos, flags, name, IS_ACCESSMETHOD); - } - - /** Creates a new function owned by this symbol. */ - public final Symbol newFunction(int pos, int flags, Name name) { - assert isTerm(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new method or function owned by this symbol. */ - public final Symbol newMethodOrFunction(int pos, int flags, Name name){ - assert isClass() || isTerm(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new label owned by this symbol. */ - public final Symbol newLabel(int pos, Name name) { - assert isTerm(): Debug.show(this); - return newTerm(pos, 0, name, IS_LABEL); - } - - /** Creates a new field owned by this symbol. */ - public final Symbol newField(int pos, int flags, Name name) { - assert isClass(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new static field owned by this symbol. */ - public final Symbol newStaticField(int pos, int flags, Name name) { - assert isClass(): Debug.show(this); - return newTerm(pos, flags, name, IS_STATIC); - } - - /** Creates a new variable owned by this symbol. */ - public final Symbol newVariable(int pos, int flags, Name name) { - assert isTerm(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new variable owned by this symbol. */ - public final Symbol newFieldOrVariable(int pos, int flags, Name name) { - assert isClass() || isTerm(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new pattern variable owned by this symbol. */ - public final Symbol newPatternVariable(int pos, Name name) { - return newVariable(pos, 0, name); - } - - /** Creates a new value parameter owned by this symbol. */ - public final Symbol newVParam(int pos, int flags, Name name) { - assert isTerm(): Debug.show(this); - return newTerm(pos, flags | PARAM, name); - } - - /** - * Creates a new value parameter owned by this symbol and - * initializes it with the type. - */ - public final Symbol newVParam(int pos, int flags, Name name, Type type) { - Symbol tparam = newVParam(pos, flags, name); - tparam.setInfo(type); - return tparam; - } - - /** - * Creates a new initialized dummy symbol for template of this - * class. - */ - public final Symbol newLocalDummy() { - assert isClass(): Debug.show(this); - Symbol local = newTerm(pos, 0, Names.LOCAL(this), IS_LOCALDUMMY); - local.setInfo(Type.NoType); - return local; - } - - /** Creates a new module owned by this symbol. */ - public final Symbol newModule(int pos, int flags, Name name) { - return new ModuleSymbol(this, pos, flags, name); - } - - /** - * Creates a new package owned by this symbol and initializes it - * with an empty scope. - */ - public final Symbol newPackage(int pos, Name name) { - return newPackage(pos, name, null); - } - - /** - * Creates a new package owned by this symbol, initializes it with - * the loader and enters it in the scope if it's non-null. - */ - public final Symbol newLoadedPackage(Name name, SymbolLoader loader, - Scope scope, SymbolOrigin origin) - { - assert loader != null: Debug.show(this) + " - " + name; - Symbol peckage = newPackage(Position.NOPOS, name, loader); - peckage.moduleClass().setOrigin(origin); - if (scope != null) scope.enterNoHide(peckage); - return peckage; - } - - /** - * Creates a new error value owned by this symbol and initializes - * it with an error type. - */ - public Symbol newErrorValue(Name name) { - Symbol symbol = newTerm(pos, SYNTHETIC, name, IS_ERROR); - symbol.setInfo(Type.ErrorType); - return symbol; - } - - /** Creates a new type alias owned by this symbol. */ - public final Symbol newTypeAlias(int pos, int flags, Name name) { - return new AliasTypeSymbol(this, pos, flags, name, 0); - } - - /** Creates a new abstract type owned by this symbol. */ - public final Symbol newAbstractType(int pos, int flags, Name name) { - return new AbsTypeSymbol(this, pos, flags, name, 0); - } - - /** Creates a new type parameter owned by this symbol. */ - public final Symbol newTParam(int pos, int flags, Name name) { - assert isTerm(): Debug.show(this); - return newAbstractType(pos, flags | PARAM, name); - } - - /** - * Creates a new type parameter owned by this symbol and - * initializes it with the type. - */ - public final Symbol newTParam(int pos, int flags, Name name, Type type) { - Symbol tparam = newTParam(pos, flags, name); - tparam.setInfo(type); - return tparam; - } - - /** - * Creates a new type alias owned by this symbol and initializes - * it with the info. - */ - public final Symbol newTypeAlias(int pos, int flags, Name name, Type info){ - Symbol alias = newTypeAlias(pos, flags, name); - alias.setInfo(info); - alias.allConstructors().setInfo(Type.MethodType(EMPTY_ARRAY, info)); - return alias; - } - - /** Creates a new class owned by this symbol. */ - public final ClassSymbol newClass(int pos, int flags, Name name) { - return newClass(pos, flags, name, 0); - } - - /** Creates a new anonymous class owned by this symbol. */ - public final ClassSymbol newAnonymousClass(int pos, Name name) { - assert isTerm(): Debug.show(this); - return newClass(pos, 0, name, IS_ANONYMOUS); - } - - /** - * Creates a new class with a linked module, both owned by this - * symbol, initializes them with the loader and enters the class - * and the module in the scope if it's non-null. - */ - public final ClassSymbol newLoadedClass(int flags, Name name, - SymbolLoader loader, Scope scope, SymbolOrigin origin) - { - assert loader != null: Debug.show(this) + " - " + name; - ClassSymbol clasz = new LinkedClassSymbol(this, flags, name); - clasz.setInfo(loader); - clasz.setOrigin(origin); - clasz.allConstructors().setInfo(loader); - clasz.linkedModule().setInfo(loader); - clasz.linkedModule().moduleClass().setInfo(loader); - clasz.linkedModule().moduleClass().setOrigin(origin); - if (scope != null) scope.enterNoHide(clasz); - if (scope != null) scope.enterNoHide(clasz.linkedModule()); - return clasz; - } - - /** - * Creates a new error class owned by this symbol and initializes - * it with an error type. - */ - public ClassSymbol newErrorClass(Name name) { - ClassSymbol symbol = newClass(pos, SYNTHETIC, name, IS_ERROR); - Scope scope = new ErrorScope(this); - symbol.setInfo(Type.compoundType(Type.EMPTY_ARRAY, scope, this)); - symbol.allConstructors().setInfo(Type.ErrorType); - return symbol; - } - - /** Creates a new term owned by this symbol. */ - final Symbol newTerm(int pos, int flags, Name name, int attrs) { - return new TermSymbol(this, pos, flags, name, attrs); - } - - /** Creates a new package owned by this symbol. */ - final Symbol newPackage(int pos, Name name, Type info) { - assert isPackageClass(): Debug.show(this); - Symbol peckage = newModule(pos, JAVA | PACKAGE, name); - if (info == null) info = Type.compoundType( - Type.EMPTY_ARRAY, new Scope(), peckage.moduleClass()); - peckage.moduleClass().setInfo(info); - return peckage; - } - - /** Creates a new class owned by this symbol. */ - final ClassSymbol newClass(int pos, int flags, Name name, int attrs) { - return new ClassSymbol(this, pos, flags, name, attrs); - } - - /** Creates a new compound class owned by this symbol. */ - final ClassSymbol newCompoundClass(Type info) { - int pos = Position.FIRSTPOS; - Name name = Names.COMPOUND_NAME.toTypeName(); - int flags = ABSTRACT | SYNTHETIC; - int attrs = IS_COMPOUND; - ClassSymbol clasz = newClass(pos, flags, name, attrs); - clasz.setInfo(info); - clasz.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clasz.typeConstructor())); - return clasz; - } - -// Copying & cloning ------------------------------------------------------ - - /** Returns a fresh symbol with the same fields as this one. - */ - public final Symbol cloneSymbol() { - return cloneSymbol(owner); - } - - /** Returns a fresh symbol with the same fields as this one and the - * given owner. - */ - public final Symbol cloneSymbol(Symbol owner) { - Symbol clone = cloneSymbolImpl(owner, attrs); - clone.setInfo(info()); - return clone; - } - - protected abstract Symbol cloneSymbolImpl(Symbol owner, int attrs); - - /** Returns a shallow copy of the given array. */ - public static Symbol[] cloneArray(Symbol[] array) { - return cloneArray(0, array, 0); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items. - */ - public static Symbol[] cloneArray(int prefix, Symbol[] array) { - return cloneArray(prefix, array, 0); - } - - /** - * Returns a shallow copy of the given array suffixed by "suffix" - * null items. - */ - public static Symbol[] cloneArray(Symbol[] array, int suffix) { - return cloneArray(0, array, suffix); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items and suffixed by "suffix" null items. - */ - public static Symbol[] cloneArray(int prefix, Symbol[] array, int suffix) { - assert prefix >= 0 && suffix >= 0: prefix + " - " + suffix; - int size = prefix + array.length + suffix; - if (size == 0) return EMPTY_ARRAY; - Symbol[] clone = new Symbol[size]; - for (int i = 0; i < array.length; i++) clone[prefix + i] = array[i]; - return clone; - } - - /** Returns the concatenation of the two arrays. */ - public static Symbol[] concat(Symbol[] array1, Symbol[] array2) { - if (array1.length == 0) return array2; - if (array2.length == 0) return array1; - Symbol[] clone = cloneArray(array1.length, array2); - for (int i = 0; i < array1.length; i++) clone[i] = array1[i]; - return clone; - } - -// Setters --------------------------------------------------------------- - - /** Set owner */ - public Symbol setOwner(Symbol owner) { - assert !isConstructor() && !isNone() && !isError(): Debug.show(this); - setOwner0(owner); - return this; - } - protected void setOwner0(Symbol owner) { - this.owner = owner; - } - - /** Set type -- this is an alias for setInfo(Type info) */ - public final Symbol setType(Type info) { return setInfo(info); } - - /** - * Set initial information valid from start of current phase. This - * information is visible in the current phase and will be - * transformed by the current phase (except if current phase is - * the first one). - */ - public Symbol setInfo(Type info) { - return setInfoAt(info, Global.instance.currentPhase); - } - - /** - * Set initial information valid from start of given phase. This - * information is visible in the given phase and will be - * transformed by the given phase. - */ - private final Symbol setInfoAt(Type info, Phase phase) { - assert info != null: Debug.show(this); - assert phase != null: Debug.show(this); - assert !isConstructor() - || info instanceof Type.LazyType - || info == Type.NoType - || info == Type.ErrorType - || info instanceof Type.MethodType - || info instanceof Type.OverloadedType - || info instanceof Type.PolyType - : "illegal type for " + this + ": " + info; - infos = new TypeIntervalList(null, info, phase); - if (info instanceof Type.LazyType) flags &= ~INITIALIZED; - else flags |= INITIALIZED; - return this; - } - - /** - * Set new information valid from start of next phase. This - * information is only visible in next phase or through - * "nextInfo". It will not be transformed by the current phase. - */ - public final Symbol updateInfo(Type info) { - return updateInfoAt(info, Global.instance.currentPhase.next); - } - - /** - * Set new information valid from start of given phase. This - * information is only visible from the start of the given phase - * which is also the first phase that will transform this - * information. - */ - private final Symbol updateInfoAt(Type info, Phase phase) { - assert info != null: Debug.show(this); - assert phase != null: Debug.show(this); - assert infos != null: Debug.show(this); - assert !phase.precedes(infos.limit()) : - Debug.show(this) + " -- " + phase + " -- " + infos.limit(); - if (infos.limit() == phase) { - if (infos.start == phase) - infos = infos.prev; - else - infos.setLimit(infos.limit().prev); - } - infos = new TypeIntervalList(infos, info, phase); - return this; - } - - /** Set type of `this' in current class - */ - public Symbol setTypeOfThis(Type tp) { - throw new ApplicationError(this + ".setTypeOfThis"); - } - - /** Set the low bound of this type variable - */ - public Symbol setLoBound(Type lobound) { - throw new ApplicationError("setLoBound inapplicable for " + this); - } - - /** Set the view bound of this type variable - */ - public Symbol setVuBound(Type lobound) { - throw new ApplicationError("setVuBound inapplicable for " + this); - } - - /** Add an auxiliary constructor to class. - */ - public void addConstructor(Symbol constr) { - throw new ApplicationError("addConstructor inapplicable for " + this); - } - -// Symbol classification ---------------------------------------------------- - - /** Does this symbol denote an error symbol? */ - public final boolean isError() { - return (attrs & IS_ERROR) != 0; - } - - /** Does this symbol denote the none symbol? */ - public final boolean isNone() { - return kind == Kinds.NONE; - } - - /** Does this symbol denote a type? */ - public final boolean isType() { - return kind == TYPE || kind == CLASS || kind == ALIAS; - } - - /** Does this symbol denote a term? */ - public final boolean isTerm() { - return kind == VAL; - } - - /** Does this symbol denote a value? */ - public final boolean isValue() { - preInitialize(); - return kind == VAL && !(isModule() && isJava()) && !isPackage(); - } - - /** Does this symbol denote a stable value? */ - public final boolean isStable() { - return kind == VAL && - ((flags & DEF) == 0) && - ((flags & STABLE) != 0 || - (flags & MUTABLE) == 0 && type().isObjectType()); - } - - /** Does this symbol have the STABLE flag? */ - public final boolean hasStableFlag() { - return (flags & STABLE) != 0; - } - - /** Is this symbol captured? */ - public final boolean isCaptured() { - return (flags & CAPTURED) != 0; - } - - /** Is this symbol static (i.e. with no outer instance)? */ - public final boolean isStatic() { - return isRoot() || hasStaticAttribute() || owner.isStaticOwner(); - } - - public final boolean hasStaticAttribute() { - return (attrs & IS_STATIC) != 0; - } - - /** Does this symbol denote a class that defines static symbols? */ - public final boolean isStaticOwner() { - // !!! remove "isJava()"? translation does not work (yet?) - return isPackageClass() || (isJava() && isModuleClass() && isStatic()); - } - - /** Is this symbol final? - */ - public final boolean isFinal() { - return - (flags & (FINAL | PRIVATE)) != 0 || isLocal() || owner.isModuleClass(); - } - - /** Does this symbol denote a variable? */ - public final boolean isVariable() { - return kind == VAL && (flags & MUTABLE) != 0; - } - - /** Does this symbol denote a view bounded type variable? */ - public final boolean isViewBounded() { - Global global = Global.instance; - return kind == TYPE && (flags & VIEWBOUND) != 0 && - global.currentPhase.id <= global.PHASE.REFCHECK.id(); - } - - /** - * Does this symbol denote a final method? A final method is one - * that can't be overridden in a subclass. This method assumes - * that this symbol denotes a method. It doesn't test it. - */ - public final boolean isMethodFinal() { - return (flags & FINAL) != 0 || isPrivate() || isLifted(); - } - - /** Does this symbol denote a sealed class symbol? */ - public final boolean isSealed() { - return (flags & SEALED) != 0; - } - - /** Does this symbol denote a method? - */ - public final boolean isInitializedMethod() { - if (infos == null) return false; - switch (rawInfo()) { - case MethodType(_, _): - case PolyType(_, _): - return true; - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isMethod()) return true; - return false; - default: - return false; - } - } - - public final boolean isMethod() { - initialize(); - return isInitializedMethod(); - } - - public final boolean isCaseFactory() { - return isMethod() && !isConstructor() && (flags & CASE) != 0; - } - - public final boolean isAbstractClass() { - preInitialize(); - return kind == CLASS && (flags & ABSTRACT) != 0 && - this != Global.instance.definitions.ARRAY_CLASS; - } - - public final boolean isOverride() { - preInitialize(); - return (flags & OVERRIDE) != 0; - } - - public final boolean isAbstractOverride() { - preInitialize(); - return (flags & (ABSTRACT | OVERRIDE)) == (ABSTRACT | OVERRIDE); - } - - /* Does this symbol denote an anonymous class? */ - public final boolean isAnonymousClass() { - return isClass() && (attrs & IS_ANONYMOUS) != 0; - } - - /** Does this symbol denote the root class or root module? - */ - public final boolean isRoot() { - return (attrs & IS_ROOT) != 0; - } - - /** Does this symbol denote something loaded from a Java class? */ - public final boolean isJava() { - preInitialize(); - return (flags & JAVA) != 0; - } - - /** Does this symbol denote a Java package? */ - public final boolean isPackage() { - return kind == VAL && (flags & PACKAGE) != 0; - } - - /** Does this symbol denote a Java package class? */ - public final boolean isPackageClass() { - return kind == CLASS && (flags & PACKAGE) != 0; - } - - /** Does this symbol have the PACKAGE flag? */ - public final boolean hasPackageFlag() { - return (flags & PACKAGE) != 0; - } - - /** Does this symbol denote a module? */ - public final boolean isModule() { - return kind == VAL && (flags & MODUL) != 0; - } - - /** Does this symbol denote a module class? */ - public final boolean isModuleClass() { - return kind == CLASS && (flags & MODUL) != 0; - } - - /** Does this symbol denote a class? */ - public final boolean isClass() { - return kind == CLASS && (flags & PACKAGE) == 0; - } - - /** Does this symbol denote a case class? */ - public final boolean isCaseClass() { - preInitialize(); - return kind == CLASS && (flags & CASE) != 0; - } - - /** Does this symbol denote a case object? */ - public final boolean isCaseModuleClass() { - return isModuleClass() && isCaseClass(); - } - - /** Does this symbol denote a uniform (i.e. parameterless) class? */ - public final boolean isTrait() { - //preInitialize(); todo: enable, problem is that then we cannot print - // during unpickle - return kind == CLASS && (flags & TRAIT) != 0; - } - - /** Does this class symbol denote a compound type symbol? */ - public final boolean isCompoundSym() { - return (attrs & IS_COMPOUND) != 0; - } - - /** Does this symbol denote a this symbol? */ - public final boolean isThisSym() { - return (attrs & IS_THISTYPE) != 0; - } - - /** Does this symbol denote an interface? */ - public final boolean isInterface() { - info(); // force delayed transformInfos that may change this flag - return (flags & INTERFACE) != 0; - } - - /** Does this symbol denote a type alias? */ - public final boolean isTypeAlias() { - return kind == ALIAS; - } - - /** Does this symbol denote an abstract type? */ - public final boolean isAbstractType() { - return kind == TYPE; - } - - /** Does this symbol denote a class type? */ - public final boolean isClassType() { - return kind == CLASS; - } - - /** Does this symbol denote a public symbol? */ - public final boolean isPublic() { - return !isProtected() && !isPrivate(); - } - - /** Does this symbol denote a protected symbol? */ - public final boolean isProtected() { - preInitialize(); - return (flags & PROTECTED) != 0; - } - - /** Does this symbol denote a private symbol? */ - public final boolean isPrivate() { - preInitialize(); - return (flags & PRIVATE) != 0; - } - - /** Has this symbol been lifted? */ - public final boolean isLifted() { - preInitialize(); - return (flags & LIFTED) != 0; - } - - /** Does this symbol denote a deferred symbol? */ - public final boolean isDeferred() { - return (flags & DEFERRED) != 0; - } - - /** Does this symbol denote a synthetic symbol? */ - public final boolean isSynthetic() { - return (flags & SYNTHETIC) != 0; - } - - /** Does this symbol denote an accessor? */ - public final boolean isAccessor() { - return (flags & ACCESSOR) != 0; - } - - /** Has this symbol the PARAMACCESSOR flag? */ - public final boolean hasParamAccessorFlag() { - return (flags & PARAMACCESSOR) != 0; - } - - /** Does this symbol denote an access method? (a method to access - * private of protected members from inner classes) */ - public final boolean isAccessMethod() { - return (attrs & IS_ACCESSMETHOD) != 0; - } - - /** Is this symbol locally defined? I.e. not a member of a class or module */ - public final boolean isLocal() { - return owner.kind == VAL && - !((flags & PARAM) != 0 && owner.isPrimaryConstructor()); - } - - /** Is this symbol a parameter? Includes type parameters of methods. - */ - public final boolean isParameter() { - return (flags & PARAM) != 0; - } - - /** Is this symbol a type parameter? - */ - public final boolean isTypeParameter() { - return kind == TYPE && (flags & PARAM) != 0; - } - - /** Is this symbol a def parameter? - */ - public final boolean isDefParameter() { - return (flags & (PARAM | DEF)) == (PARAM | DEF); - } - - /** Is this class locally defined? - * A class is local, if - * - it is anonymous, or - * - its owner is a value - * - it is defined within a local class - */ - public final boolean isLocalClass() { - return isClass() && - (isAnonymousClass() || - owner.isValue() || - owner.isLocalClass()); - } - - /** Is this symbol an instance initializer? */ - public boolean isInitializer() { - return false; - } - - /** Is this symbol a constructor? */ - public final boolean isConstructor() { - return (attrs & IS_CONSTRUCTOR) != 0; - } - - /** Is this symbol the primary constructor of a type? */ - public final boolean isPrimaryConstructor() { - return isConstructor() && this == constructorClass().primaryConstructor(); - } - - /** Symbol was preloaded from package - */ - public final boolean isExternal() { - return pos == Position.NOPOS; - } - - /** Is this symbol an overloaded symbol? */ - public final boolean isOverloaded() { - Type tp = rawInfo(); - return - tp instanceof Type.OverloadedType || - tp instanceof LazyOverloadedType; - } - - /** Does this symbol denote a label? */ - public final boolean isLabel() { - return (attrs & IS_LABEL) != 0; - } - - /** Is this symbol accessed? */ - public final boolean isAccessed() { - return (flags & ACCESSED) != 0; - } - - /** The variance of this symbol as an integer - */ - public int variance() { - if ((flags & COVARIANT) != 0) return 1; - else if ((flags & CONTRAVARIANT) != 0) return -1; - else return 0; - } - -// Symbol names ---------------------------------------------------------------- - - /** Get the simple name of this Symbol (this is always a term name) - */ - public Name simpleName() { - if (isConstructor()) return constructorClass().name.toTermName(); - return name; - } - -// Symbol origin -------------------------------------------------------------- - - /** Returns the origin of this symbol. */ - public SymbolOrigin getOrigin() { - Symbol clasz = getMainClassOrNone(); - return (clasz != this ? clasz : owner()).getOrigin(); - } - - /** Sets the origin of this symbol. */ - public void setOrigin(SymbolOrigin origin) { - throw Debug.abort("not a class", this); - } - - /** - * Returns the main owner of this symbol. The main owner of a - * symbol is: - * - its module class for modules - * - its constructed class for constructors and factory methods - * - its owner for other symbols - * - * @see Symbol#getMainClassOrNone() - */ - public Symbol getMainOwner() { - if (isModule()) - return moduleClass(); - if (isConstructor()) - return constructorClass(); - if (isCaseFactory()) - return type().resultType().symbol(); - return owner(); - } - - /** - * Returns the main class of this symbol. The main class of a - * symbol is: - * - itself for non-compound classes and NONE - * - the main class of its main owner for other symbols - * - * This implies that the main class of a symbol is the first - * enclosing class of that symbol excepted for modules, - * constructors and factory methods. The main class of modules is - * their module class and the main class of constructors and - * factory methods is their constructed class. If a the symbol is - * not linked to a class through its owner, the method returns - * the symbol NONE. - * - * The main class of a symbol can be understood as the class that - * declared that symbol. - * - * @see Symbol@getMainOwner() - */ - public Symbol getMainClassOrNone() { - if (isNone() || (isClassType() && !isCompoundSym())) - return this; - return getMainOwner().getMainClassOrNone(); - } - - /** - * Determines the enclosing package of this symbol and returns the - * module class of that package. Note that the enclosing package - * of a package is itself. If a symbol has no enclosing package, - * the method returns the symbol NONE. - */ - public Symbol getEnclosingPackageClassOrNone() { - Symbol clasz = getMainClassOrNone(); - while (!clasz.isNone() && !clasz.isPackageClass()) - clasz = clasz.owner().getMainClassOrNone(); - return clasz; - } - - /** - * Returns the source directory of this symbol or "null" if it is - * unknown. The source directory of a symbol is the directory - * corresponding to the enclosing package of that symbol. - * - * @see Symbol@getEnclosingPackageClassOrNone() - */ - public final AbstractFile getSourceDirectoryOrNull() { - if (isNone()) return null; - if (!isPackageClass()) - return getEnclosingPackageClassOrNone().getSourceDirectoryOrNull(); - - switch (getOrigin()) { - case Directory(AbstractFile file): - return file; - default: - AbstractFile parent = owner().getSourceDirectoryOrNull(); - if (parent == null) return null; - return parent.lookupName(name.toString(), true); - } - } - - /** - * Returns the source file of this symbol or "null" if it is - * unknown. - */ - public final AbstractFile getSourceFileOrNull() { - switch (getOrigin()) { - case ClassFile(_, String sourcefile): - if (sourcefile == null) return null; - AbstractFile parent = getSourceDirectoryOrNull(); - if (parent == null) return null; - return parent.lookupName(sourcefile, false); - case ScalaFile(AbstractFile file): - return file; - case ScalaUnit(CompilationUnit unit): - return unit.source.getFile(); - default: - return null; - } - } - - /** - * Returns the compilation unit of this symbol or "null" if it is - * unknown or if the symbol has no associated compilation unit. - */ - public final CompilationUnit getUnitOrNull() { - switch (getOrigin()) { - case ScalaUnit(CompilationUnit unit): - return unit; - default: - return null; - } - } - -// Acess to related symbols ----------------------------------------------------- - - /** Get type parameters */ - public Symbol[] typeParams() { - return EMPTY_ARRAY; - } - - /** Get value parameters */ - public Symbol[] valueParams() { - return EMPTY_ARRAY; - } - - /** Get result type */ - public final Type resultType() { - return type().resultType(); - } - - /** Get type parameters at start of next phase */ - public final Symbol[] nextTypeParams() { - Global.instance.nextPhase(); - Symbol[] tparams = typeParams(); - Global.instance.prevPhase(); - return tparams; - } - - /** Get value parameters at start of next phase */ - public final Symbol[] nextValueParams() { - Global.instance.nextPhase(); - Symbol[] vparams = valueParams(); - Global.instance.prevPhase(); - return vparams; - } - - /** Get result type at start of next phase */ - public final Type nextResultType() { - return nextType().resultType(); - } - - /** Get all constructors of class */ - public Symbol allConstructors() { - return NONE; - } - - /** Get primary constructor of class */ - public Symbol primaryConstructor() { - return NONE; - } - - /** - * Returns the class linked to this module or null if there is no - * such class. The returned value remains the same for the whole - * life of the symbol. - * - * See method "linkedModule" to learn more about linked modules - * and classes. - */ - public ClassSymbol linkedClass() { - assert isModule(): "not a module: " + Debug.show(this); - return null; - } - - /** - * Returns the module linked to this class or null if there is no - * such module. The returned value remains the same for the whole - * life of the symbol. - * - * Linked modules and classes are intended to be used by the - * symbol table loader. They are needed because it is impossible - * to know from the name of a class or source file if it defines a - * class or a module. For that reason a class and a module (each - * linked to the other) are created for each of those files. Once - * the file is read the class, the module or both are initialized - * depending on what the file defines. - * - * It is guaranteed that if a class "c" has a linked module then - * "c.linkedModule().linkedClasss() == c" and that if a module "m" - * has a linked class then "m.linkedClasss().linkedModule() == m". - * - * The linked module of a Java class, is the module that contains - * the static members of that class. A Java class has always a - * linked module. - * - * The linked module of a Scala class, is the module with the same - * name declared in the same scope. A Scala class may or may not - * have a linked module. However, this does not depend on the - * presence or absence of a module with the same name but on how - * the class is created. Therefore a Scala class may have no - * linked module even though there exists a module with the same - * name in the same scope. A Scala class may also have a linked - * module even though there exists no module with the same name in - * the same scope. In the latter case, the linked would be - * initialized to NoType (which prevents accesses to it). - * - * There is a last catch about linked modules. It may happen that - * the symbol returned by "linkedModule" is not a module (and that - * method "linkedClass" works on a non-module symbol). At creation - * time, linked modules are always modules, but at initialization - * time, it may be discovered that the module is in fact a case - * class factory method. In that case, the module is downgraded to - * a non-module term. This implies that from then on calls to its - * method "moduleClass" will fail, but the links defined by the - * methods "linkedModule" and "linkedClass" remain unchanged. - */ - public ModuleSymbol linkedModule() { - assert isClassType(): "not a class: " + Debug.show(this); - return null; - } - - /** Get owner */ - public Symbol owner() { - return owner; - } - - /** Get owner, but if owner is primary constructor of a class, - * get class symbol instead. This is useful for type parameters - * and value parameters in classes which have the primary constructor - * as owner. - */ - public Symbol classOwner() { - Symbol owner = owner(); - Symbol clazz = owner.constructorClass(); - if (clazz.primaryConstructor() == owner) return clazz; - else return owner; - } - - /** The next enclosing class */ - public Symbol enclClass() { - return owner().enclClass(); - } - - /** The next enclosing method */ - public Symbol enclMethod() { - return isMethod() ? this : owner().enclMethod(); - } - - /** If this is a constructor, return the class it constructs. - * Otherwise return the symbol itself. - */ - public Symbol constructorClass() { - return this; - } - - /** - * Returns the class of this module. This method may be invoked - * only on module symbols. It returns always a non-null module - * class symbol whose identity never changes. - */ - public ModuleClassSymbol moduleClass() { - throw Debug.abort("not a module", this); - } - - /** - * Returns the source module of this module class. This method may - * be invoked only on module class symbols. It returns always a - * non-null module symbol whose identity never changes. - * - * This method should be used with great care. If possible, one - * should always use moduleClass instead. For example, one should - * write "m.moduleClass()==c" rather than "m==c.sourceModule()". - * - * This method is problematic because the module - module-class - * relation is not a one - one relation. There might be more than - * one module that share the same module class. In that case, the - * source module of the module class is the module that created - * the class. This implies that "m.moduleClass().sourceModule()" - * may be different of "m". However, its is guaranteed that - * "c.sourceModule().moduleClass()" always returns "c". - * - * Phases like "AddInterfaces" and "ExpandMixins" are two examples - * of phases that create additional modules referring the same - * module class. - * - * Even if a module class is related to only one module, the use - * of this method may still be dangerous. The problem is that - * modules and module classes are not always as related as one - * might expect. For example, modules declared in a function are - * lifted out of the function by phase "LambdaLift". During this - * process, the module value is transformed into a module method - * with a "Ref" argument. If the "sourceModule" method is used to - * replace references to module classes by references to their - * source modules and this is done it naively with the class of a - * lifted module, it will yield wrong code because the the "Ref" - * argument will be missing. - */ - public ModuleSymbol sourceModule() { - throw Debug.abort("not a module class", this); - } - - /** if type is a (possibly lazy) overloaded type, return its alternatves - * else return array consisting of symbol itself - */ - public Symbol[] alternativeSymbols() { - Symbol[] alts = type().alternativeSymbols(); - if (alts.length == 0) return new Symbol[]{this}; - else return alts; - } - - /** if type is a (possibly lazy) overloaded type, return its alternatves - * else return array consisting of type itself - */ - public Type[] alternativeTypes() { - return type().alternativeTypes(); - } - - /** if type is a overloaded type, return first stable alternative - * else return symbol itself - */ - public Symbol stableAlternative() { - switch (type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isStable()) return alts[i]; - } - return this; - } - - /** The symbol accessed by this accessor function. - */ - public Symbol accessed() { - assert (flags & ACCESSOR) != 0; - String name1 = name.toString(); - if (name1.endsWith(Names._EQ.toString())) - name1 = name1.substring(0, name1.length() - Names._EQ.length()); - return owner.lookup(Name.fromString(name1 + "$")); - } - - /** The members of this class or module symbol - */ - public Scope members() { - return info().members(); - } - - /** Lookup symbol with given name; return Symbol.NONE if not found. - */ - public Symbol lookup(Name name) { - return info().lookup(name); - } - -// Symbol types -------------------------------------------------------------- - - /** Was symbol's type updated during given phase? */ - public final boolean isUpdatedAt(Phase phase) { - Phase next = phase.next; - TypeIntervalList infos = this.infos; - while (infos != null) { - if (infos.start == next) return true; - if (infos.limit().precedes(next)) return false; - infos = infos.prev; - } - return false; - } - - /** Is this symbol locked? */ - public final boolean isLocked() { - return (flags & LOCKED) != 0; - } - - /** Is this symbol initialized? */ - public final boolean isInitialized() { - return (flags & INITIALIZED) != 0; - } - - /** Initialize the symbol */ - public final Symbol initialize() { - info(); - return this; - } - - /** Make sure symbol is entered - */ - public final void preInitialize() { - //todo: clean up - if (infos.info instanceof SymbolLoader) - infos.info.complete(this); - } - - /** Get info at start of current phase; This is: - * for a term symbol, its type - * for a type variable, its bound - * for a type alias, its right-hand side - * for a class symbol, the compound type consisting of - * its baseclasses and members. - */ - public final Type info() { - //if (isModule()) moduleClass().initialize(); - if ((flags & INITIALIZED) == 0) { - Global global = Global.instance; - Phase current = global.currentPhase; - global.currentPhase = rawFirstInfoStartPhase(); - Type info = rawFirstInfo(); - assert info != null : this; - if ((flags & LOCKED) != 0) { - setInfo(Type.ErrorType); - flags |= INITIALIZED; - throw new CyclicReference(this, info); - } - flags |= LOCKED; - //System.out.println("completing " + this);//DEBUG - info.complete(this); - flags = flags & ~LOCKED; - if (info instanceof SourceCompleter && (flags & SNDTIME) == 0) { - flags |= SNDTIME; - Type tp = info(); - flags &= ~SNDTIME; - } else { - assert !(rawInfo() instanceof Type.LazyType) : this; - //flags |= INITIALIZED; - } - //System.out.println("done: " + this);//DEBUG - global.currentPhase = current; - } - return rawInfo(); - } - - /** Get info at start of next phase - */ - public final Type nextInfo() { - Global.instance.nextPhase(); - Type info = info(); - Global.instance.prevPhase(); - return info; - } - - /** Get info at start of given phase - */ - protected final Type infoAt(Phase phase) { - Global global = phase.global; - Phase current = global.currentPhase; - global.currentPhase = phase; - Type info = info(); - global.currentPhase = current; - return info; - } - - /** Get info at start of current phase, without forcing lazy types. - */ - public final Type rawInfo() { - return rawInfoAt(Global.instance.currentPhase); - } - - /** Get info at start of next phase, without forcing lazy types. - */ - public final Type rawNextInfo() { - Global.instance.nextPhase(); - Type info = rawInfo(); - Global.instance.prevPhase(); - return info; - } - - /** Get info at start of given phase, without forcing lazy types. - */ - private final Type rawInfoAt(Phase phase) { - //if (infos == null) return Type.NoType;//DEBUG - assert infos != null : this; - assert phase != null : this; - if (infos.limit().id <= phase.id) { - switch (infos.info) { - case LazyType(): - // don't force lazy types - return infos.info; - } - while (infos.limit() != phase) { - Phase limit = infos.limit(); - Type info = transformInfo(limit, infos.info); - assert info != null: Debug.show(this) + " -- " + limit; - if (info != infos.info) { - infos = new TypeIntervalList(infos, info, limit.next); - } else { - infos.setLimit(limit.next); - } - } - return infos.info; - } else { - TypeIntervalList infos = this.infos; - while (phase.id < infos.start.id && infos.prev != null) - infos = infos.prev; - return infos.info; - } - } - // where - private Type transformInfo(Phase phase, Type info) { - Global global = phase.global; - Phase current = global.currentPhase; - boolean keepInheritedOverloaded = current.id <= global.PHASE.UNCURRY.id(); - switch (info) { - case ErrorType: - case NoType: - return info; - case OverloadedType(Symbol[] alts, Type[] alttypes): - global.currentPhase = phase.next; - int n = 0; - boolean altChanged = false; - for (int i = 0; i < alts.length; i++) { - Type type = alts[i].info(); - if (keepInheritedOverloaded || - alts[i].owner() == owner()) n++; - if (alts[i].info() != alttypes[i]) altChanged = true; - } - Type result; - if (n < alts.length) { - Symbol[] symbols = new Symbol[n]; - Type[] types = new Type[n]; - int j = 0; - for (int i = 0; i < alts.length; i++) { - if (keepInheritedOverloaded || - alts[i].owner() == owner()) { - symbols[j] = alts[i]; - types[j] = alts[i].info(); - j++; - } else - if (Global.instance.debug) Global.instance.log("removing inherited alternatve " + alts[i] + ":" + alttypes[i]);//debug - } - result = Type.OverloadedType(symbols, types); - } else if (altChanged) { - Type[] types = new Type[alttypes.length]; - for (int i = 0; i < alts.length; i++) { - types[i] = alts[i].info(); - } - result = Type.OverloadedType(alts, types); - } else { - result = info; - } - global.currentPhase = current; - return result; - default: - global.currentPhase = phase; - info = phase.transformInfo(this, info); - global.currentPhase = current; - return info; - } - } - - /** Get first defined info, without forcing lazy types. - */ - public final Type rawFirstInfo() { - TypeIntervalList infos = this.infos; - assert infos != null : this; - while (infos.prev != null) infos = infos.prev; - return infos.info; - } - - /** Get phase that first defined an info, without forcing lazy types. - */ - public final Phase rawFirstInfoStartPhase() { - TypeIntervalList infos = this.infos; - assert infos != null : this; - while (infos.prev != null) infos = infos.prev; - return infos.start; - } - - /** Get type at start of current phase. The type of a symbol is: - * for a type symbol, the type corresponding to the symbol itself - * for a term symbol, its usual type - */ - public Type type() { - return info(); - } - public Type getType() { - return info(); - } - - /** Get type at start of next phase - */ - public final Type nextType() { - Global.instance.nextPhase(); - Type type = type(); - Global.instance.prevPhase(); - return type; - } - - /** The infos of these symbols as an array. - */ - static public Type[] info(Symbol[] syms) { - Type[] tps = new Type[syms.length]; - for (int i = 0; i < syms.length; i++) - tps[i] = syms[i].info(); - return tps; - } - - /** The types of these symbols as an array. - */ - static public Type[] type(Symbol[] syms) { - Type[] tps = new Type[syms.length]; - for (int i = 0; i < syms.length; i++) - tps[i] = syms[i].type(); - return tps; - } - static public Type[] getType(Symbol[] syms) { - return type(syms); - } - - /** Get static type. */ - public final Type staticType() { - return staticType(Type.EMPTY_ARRAY); - } - /** Get static type with given type argument. */ - public final Type staticType(Type arg0) { - return staticType(new Type[]{arg0}); - } - /** Get static type with given type arguments. */ - public final Type staticType(Type arg0, Type arg1) { - return staticType(new Type[]{arg0, arg1}); - } - /** Get static type with given type arguments. */ - public final Type staticType(Type[] args) { - Type prefix = owner.staticPrefix(); - if (isType()) return Type.typeRef(prefix, this, args); - assert args.length == 0: Debug.show(this, args); - return prefix.memberType(this); - } - - /** Get static prefix. */ - public final Type staticPrefix() { - assert isStaticOwner(): Debug.show(this) + " - " + isTerm() + " - " + isModuleClass() + " - " + owner().isStaticOwner() + " - " + isJava(); - Global global = Global.instance; - if (global.PHASE.EXPLICITOUTER.id() < global.currentPhase.id) - return Type.NoPrefix; - if (isRoot()) return thisType(); - assert sourceModule().owner() == owner(): Debug.show(this); - assert sourceModule().type().isObjectType(): Debug.show(this); - return Type.singleType(owner.staticPrefix(), sourceModule()); - } - - /** The type constructor of a symbol is: - * For a type symbol, the type corresponding to the symbol itself, excluding - * parameters. - * Not applicable for term symbols. - */ - public Type typeConstructor() { - throw new ApplicationError("typeConstructor inapplicable for " + this); - } - - /** The low bound of this type variable - */ - public Type loBound() { - return Global.instance.definitions.ALL_TYPE(); - } - - /** The view bound of this type variable - */ - public Type vuBound() { - return Global.instance.definitions.ANY_TYPE(); - } - - /** Get this.type corresponding to this symbol - */ - public Type thisType() { - return Type.NoPrefix; - } - - /** Get type of `this' in current class. - */ - public Type typeOfThis() { - return type(); - } - - /** Get this symbol of current class - */ - public Symbol thisSym() { return this; } - - - /** A total ordering between symbols that refines the class - * inheritance graph (i.e. subclass.isLess(superclass) always holds). - */ - public boolean isLess(Symbol that) { - if (this == that) return false; - int diff; - if (this.isType()) { - if (that.isType()) { - diff = this.closure().length - that.closure().length; - if (diff > 0) return true; - if (diff < 0) return false; - } else { - return true; - } - } else if (that.isType()) { - return false; - } - return this.id < that.id; - } - - /** Return the symbol's type itself followed by all its direct and indirect - * base types, sorted by isLess(). Overridden for class symbols. - */ - public Type[] closure() { - return info().closure(); - } - - /** Return position of `c' in the closure of this type; -1 if not there. - */ - public int closurePos(Symbol c) { - if (this == c) return 0; - if (c.isCompoundSym()) return -1; - Type[] closure = closure(); - int lo = 0; - int hi = closure.length - 1; - while (lo <= hi) { - int mid = (lo + hi) / 2; - Symbol clsym = closure[mid].symbol(); - if (c == clsym) return mid; - else if (c.isLess(clsym)) hi = mid - 1; - else if (clsym.isLess(c)) lo = mid + 1; - else throw new ApplicationError(); - } - return -1; - } - - public Type baseType(Symbol sym) { - int i = closurePos(sym); - if (i >= 0) return closure()[i]; - else return Type.NoType; - } - - /** Is this class a subclass of `c'? I.e. does it have a type instance - * of `c' as indirect base class? - */ - public boolean isSubClass(Symbol c) { - return this == c || - c.isError() || - closurePos(c) >= 0 || - this == Global.instance.definitions.ALL_CLASS || - (this == Global.instance.definitions.ALLREF_CLASS && - c != Global.instance.definitions.ALL_CLASS && - c.isSubClass(Global.instance.definitions.ANYREF_CLASS)); - } - - /** Get base types of this symbol */ - public Type[] parents() { - return info().parents(); - } - -// ToString ------------------------------------------------------------------- - - /** String representation of symbol's simple name. - * Translates expansions of operators back to operator symbol. E.g. - * $eq => =. - */ - public String nameString() { - return NameTransformer.decode(simpleName()); - } - - /** String representation, including symbol's kind - * e.g., "class Foo", "function Bar". - */ - public String toString() { - return new SymbolTablePrinter().printSymbolKindAndName(this).toString(); - } - - /** String representation of location. - */ - public String locationString() { - if (owner.kind == CLASS && - !owner.isAnonymousClass() && !owner.isCompoundSym() || - Global.instance.debug) - return " in " + - (owner.isModuleClass() ? owner.sourceModule() : owner); - else - return ""; - } - - /** String representation of definition. - */ - public String defString() { - return new SymbolTablePrinter().printSignature(this).toString(); - } - - public static String[] defString(Symbol[] defs) { - String[] strs = new String[defs.length]; - for (int i = 0; i < defs.length; i++) - strs[i] = defs[i].defString(); - return strs; - } - -// Overloading and Overriding ------------------------------------------- - - /** Return first alternative if this has a (possibly lazy) - * overloaded type, otherwise symbol itself. - * Needed in ClassSymbol.primaryConstructor() and in UnPickle. - */ - public Symbol firstAlternative() { - if (infos == null) - return this; - else if (infos.info instanceof Type.OverloadedType) { - Symbol result = infos.info.alternativeSymbols()[0]; - assert !result.isOverloaded(); - return result; - } else if (infos.info instanceof LazyOverloadedType) - return ((LazyOverloadedType) infos.info).sym1.firstAlternative(); - else - return this; - } - - /** Add another overloaded alternative to this symbol. - */ - public Symbol overloadWith(Symbol that) { - throw new ApplicationError("overloadWith inapplicable for " + this); - } - - /** A lazy type which, when forced computed the overloaded type - * of symbols `sym1' and `sym2'. It also checks that this type is well-formed. - */ - public static class LazyOverloadedType extends Type.LazyType { - Symbol sym1; - Symbol sym2; - LazyOverloadedType(Symbol sym1, Symbol sym2) { - this.sym1 = sym1; - this.sym2 = sym2; - } - - public Symbol[] alternativeSymbols() { - Symbol[] alts1 = sym1.alternativeSymbols(); - Symbol[] alts2 = sym2.alternativeSymbols(); - Symbol[] alts3 = new Symbol[alts1.length + alts2.length]; - System.arraycopy(alts1, 0, alts3, 0, alts1.length); - System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length); - return alts3; - } - - public Type[] alternativeTypes() { - Type[] alts1 = sym1.alternativeTypes(); - Type[] alts2 = sym2.alternativeTypes(); - Type[] alts3 = new Type[alts1.length + alts2.length]; - System.arraycopy(alts1, 0, alts3, 0, alts1.length); - System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length); - return alts3; - } - - public void complete(Symbol overloaded) { - overloaded.setInfo( - Type.OverloadedType( - alternativeSymbols(), alternativeTypes())); - } - - public String toString() { - return "LazyOverloadedType(" + sym1 + "," + sym2 + ")"; - } - } - - /** - * Returns the symbol in type "base" which is overridden by this - * symbol in class "this.owner()". Returns "NONE" if no such - * symbol exists. The type "base" must be a supertype of class - * "this.owner()". If "exact" is true, overriding is restricted to - * symbols that have the same type. The method may return this - * symbol only if "base.symbol()" is equal to "this.owner()". - */ - public final Symbol overriddenSymbol(Type base, boolean exact) { - return overriddenSymbol(base, owner(), exact); - } - public final Symbol overriddenSymbol(Type base) { - return overriddenSymbol(base, false); - } - - /** - * Returns the symbol in type "base" which is overridden by this - * symbol in "clasz". Returns "NONE" if no such symbol exists. The - * type "base" must be a supertype of "clasz" and "this.owner()" - * must be a superclass of "clasz". If "exact" is true, overriding - * is restricted to symbols that have the same type. The method - * may return this symbol if "base.symbol()" is a subclass of - * "this.owner()". - */ - public final Symbol overriddenSymbol(Type base, Symbol clasz, boolean exact) { - Type.Relation relation = exact - ? Type.Relation.SameType - : Type.Relation.SuperType; - return base.lookup(this, clasz.thisType(), relation); - } - public final Symbol overriddenSymbol(Type base, Symbol clasz) { - return overriddenSymbol(base, clasz, false); - } - - /** - * Returns the symbol in type "sub" which overrides this symbol in - * class "sub.symbol()". Returns this symbol if no such symbol - * exists. The class "sub.symbol()" must be a subclass of - * "this.owner()". If "exact" is true, overriding is restricted to - * symbols that have the same type. - */ - public final Symbol overridingSymbol(Type sub, boolean exact) { - Type.Relation relation = exact - ? Type.Relation.SameType - : Type.Relation.SubType; - return sub.lookup(this, sub, relation); - } - public final Symbol overridingSymbol(Type sub) { - return overridingSymbol(sub, false); - } - - /** Does this symbol override that symbol? - */ - public boolean overrides(Symbol that) { - return - ((this.flags | that.flags) & PRIVATE) == 0 && - this.name == that.name && - owner.thisType().memberType(this).derefDef().isSubType( - owner.thisType().memberType(that).derefDef()); - } - - /** Reset symbol to initial state - */ - public void reset(Type completer) { - this.flags &= SOURCEFLAGS; - this.pos = 0; - this.infos = null; - this.setInfo(completer); - } - - /** - * Returns the symbol to use in case of a rebinding due to a more - * precise type prefix. - */ - public Symbol rebindSym() { - return this; - } - - /** return a tag which (in the ideal case) uniquely identifies - * class symbols - */ - public int tag() { - return name.toString().hashCode(); - } - - public void addInheritedOverloaded(Type owntype) { - Symbol sym = Type.lookupNonPrivate(owner.parents(), name); - if (sym.kind == VAL) { - Type symtype = owner.thisType().memberType(sym); - switch (symtype) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) - addInheritedOverloaded(owntype, alts[i], alttypes[i]); - break; - default: - addInheritedOverloaded(owntype, sym, symtype); - } - } - } - - public void addInheritedOverloaded(Type owntype, Symbol sym, Type symtype) { - if (!owntype.overrides(symtype)) { - if (Global.instance.debug) Global.instance.log(owner() + " inherits overloaded: " + sym + ":" + symtype + sym.locationString());//debug - owner().members().lookupEntry(name).setSymbol(overloadWith(sym)); - //System.out.println("type is now: " + owner().members().lookup(name).type()); - } - } - - public Type removeInheritedOverloaded(Type owntype) { - switch (owntype) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - int n = 0; - for (int i = 0; i < alts.length; i++) - if (alts[i].owner() == owner()) n++; - if (n < alts.length) { - Symbol[] alts1 = new Symbol[n]; - Type[] alttypes1 = new Type[n]; - int j = 0; - for (int i = 0; i < alts.length; i++) { - if (alts[i].owner() == owner()) { - alts1[j] = alts[i]; - alttypes1[j] = alttypes[i]; - j++; - } else - if (Global.instance.debug) Global.instance.log("removing inherited alternatve " + alts[i] + ":" + alttypes[i]);//debug - } - return Type.OverloadedType(alts1, alttypes1); - } else { - return owntype; - } - default: - return owntype; - } - } -} - -/** A class for term symbols - */ -public // !!! for java -Xfuture -class TermSymbol extends Symbol { - - /** Constructor */ - TermSymbol(Symbol owner, int pos, int flags, Name name, int attrs) { - super(VAL, owner, pos, flags, name, attrs); - assert name.isTermName(): Debug.show(this); - } - - public boolean isInitializer() { - return name == Names.INITIALIZER; - } - - public Symbol[] typeParams() { - return type().typeParams(); - } - - public Symbol[] valueParams() { - return type().valueParams(); - } - - protected Symbol cloneSymbolImpl(Symbol owner, int attrs) { - return new TermSymbol(owner, pos, flags, name, attrs); - } - - /** Add another overloaded alternative to this symbol. - */ - public Symbol overloadWith(Symbol that) { - assert this.name == that.name : Debug.show(this) + " <> " + Debug.show(that); - //assert this.owner == that.owner : Debug.show(this) + " != " + Debug.show(that); - assert this.isConstructor() == that.isConstructor(); - - int overflags; - //if (this.owner == that.owner) - overflags = (this.flags & that.flags & - (JAVA | ACCESSFLAGS | DEFERRED | PARAM | SYNTHETIC)) | - ((this.flags | that.flags) & ACCESSOR); - // else // it's an inherited overloaded alternative - // overflags = this.flags & SOURCEFLAGS; - Symbol overloaded = (this.isConstructor()) - ? this.constructorClass().newConstructor(this.constructorClass().pos, overflags) - : owner().newTerm(pos, overflags, name, 0); - overloaded.setInfo(new LazyOverloadedType(this, that)); - return overloaded; - } -} - -/** A class for constructor symbols */ -final class ConstructorSymbol extends TermSymbol { - - /** The constructed class */ - private final Symbol clasz; - - /** Initializes this instance. */ - ConstructorSymbol(Symbol clasz, int pos, int flags) { - super(clasz.owner(), pos, flags, Names.CONSTRUCTOR, IS_CONSTRUCTOR); - this.clasz = clasz; - } - - public boolean isInitializer() { - return false; - } - - public Symbol constructorClass() { - return clasz; - } - - protected final Symbol cloneSymbolImpl(Symbol owner, int attrs) { - throw Debug.abort("illegal clone of constructor", this); - } - -} - -/** A class for module symbols */ -public class ModuleSymbol extends TermSymbol { - - /** The module class */ - private final ModuleClassSymbol clasz; - - /** Initializes this instance. */ - private ModuleSymbol(Symbol owner, int pos, int flags, Name name, - int attrs, ModuleClassSymbol clasz) - { - super(owner, pos, flags | MODUL | FINAL | STABLE, name, attrs); - this.clasz = clasz != null ? clasz : new ModuleClassSymbol(this); - setType(Type.typeRef(owner().thisType(), this.clasz,Type.EMPTY_ARRAY)); - } - - /** Initializes this instance. */ - ModuleSymbol(Symbol owner, int pos, int flags, Name name) { - this(owner, pos, flags, name, 0, null); - } - - public ModuleClassSymbol moduleClass() { - // test may fail because loaded modules may be downgraded to - // case class factory methods (see Symbol#linkedModule()) - - assert isModule(): Debug.show(this); - return clasz; - } - - protected final Symbol cloneSymbolImpl(Symbol owner, int attrs) { - return new ModuleSymbol(owner, pos, flags, name, attrs, clasz); - } - -} - -/** - * A class for linked module symbols - * - * @see Symbol#linkedModule() - */ -public // !!! for java -Xfuture -final class LinkedModuleSymbol extends ModuleSymbol { - - /** The linked class */ - private final LinkedClassSymbol clasz; - - /** Initializes this instance. */ - LinkedModuleSymbol(LinkedClassSymbol clasz) { - super(clasz.owner(), clasz.pos, clasz.flags & JAVA, - clasz.name.toTermName()); - this.clasz = clasz; - } - - public ClassSymbol linkedClass() { - return clasz; - } - -} - -/** A base class for all type symbols. - * It has AliasTypeSymbol, AbsTypeSymbol, ClassSymbol as subclasses. - */ -public // !!! for java -Xfuture -abstract class TypeSymbol extends Symbol { - - /** The history of closures of this symbol */ - private final History/*<Type[]>*/ closures; - - /** A cache for type constructors - */ - private Type tycon = null; - - /** The primary constructor of this type */ - private Symbol constructor; - - /** Constructor */ - public TypeSymbol(int kind, Symbol owner, int pos, int flags, Name name, int attrs) { - super(kind, owner, pos, flags, name, attrs); - this.closures = new ClosureHistory(); - assert name.isTypeName() : this; - this.constructor = newConstructor(pos, flags & CONSTRFLAGS); - } - - protected final void copyConstructorInfo(TypeSymbol other) { - { - Type info = primaryConstructor().info().cloneType( - primaryConstructor(), other.primaryConstructor()); - if (!isTypeAlias()) info = fixConstrType(info, other); - other.primaryConstructor().setInfo(info); - } - Symbol[] alts = allConstructors().alternativeSymbols(); - for (int i = 1; i < alts.length; i++) { - Symbol constr = other.newConstructor(alts[i].pos, alts[i].flags); - other.addConstructor(constr); - Type info = alts[i].info().cloneType(alts[i], constr); - if (!isTypeAlias()) info = fixConstrType(info, other); - constr.setInfo(info); - } - } - - private final Type fixConstrType(Type type, Symbol clone) { - switch (type) { - case MethodType(Symbol[] vparams, Type result): - result = fixConstrType(result, clone); - return new Type.MethodType(vparams, result); - case PolyType(Symbol[] tparams, Type result): - result = fixConstrType(result, clone); - return new Type.PolyType(tparams, result); - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym != this && isTypeAlias() && owner().isCompoundSym()) - return type; - assert sym == this: Debug.show(sym) + " != " + Debug.show(this); - return Type.typeRef(pre, clone, args); - case LazyType(): - return type; - default: - throw Debug.abort("unexpected constructor type:" + clone + ":" + type); - } - } - - /** add a constructor - */ - public final void addConstructor(Symbol constr) { - assert constr.isConstructor(): Debug.show(constr); - constructor = constructor.overloadWith(constr); - } - - /** Get primary constructor */ - public final Symbol primaryConstructor() { - return constructor.firstAlternative(); - } - - /** Get all constructors */ - public final Symbol allConstructors() { - return constructor; - } - - /** Get type parameters */ - public final Symbol[] typeParams() { - return primaryConstructor().info().typeParams(); - } - - /** Get value parameters */ - public final Symbol[] valueParams() { - return (kind == CLASS) ? primaryConstructor().info().valueParams() - : Symbol.EMPTY_ARRAY; - } - - /** Get type constructor */ - public final Type typeConstructor() { - if (tycon == null) - tycon = Type.typeRef(owner().thisType(), this, Type.EMPTY_ARRAY); - return tycon; - } - - public Symbol setOwner(Symbol owner) { - tycon = null; - constructor.setOwner0(owner); - switch (constructor.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) alts[i].setOwner0(owner); - } - return super.setOwner(owner); - } - - /** Get type */ - public final Type type() { - return primaryConstructor().type().resultType(); - } - public final Type getType() { - return primaryConstructor().type().resultType(); - } - - /** - * Get closure at start of current phase. The closure of a symbol - * is a list of types which contains the type of the symbol - * followed by all its direct and indirect base types, sorted by - * isLess(). - */ - public final Type[] closure() { - if (kind == ALIAS) return info().symbol().closure(); - if ((flags & CLOSURELOCK) != 0 && Global.instance.currentPhase.id <= Global.instance.PHASE.REFCHECK.id()) - throw new Type.Error("illegal cyclic reference involving " + this); - flags |= CLOSURELOCK; - Type[] result = (Type[])closures.getValue(this); - flags &= ~CLOSURELOCK; - return result; - } - - public void reset(Type completer) { - super.reset(completer); - closures.reset(); - tycon = null; - } - - - protected final Symbol cloneSymbolImpl(Symbol owner, int attrs) { - TypeSymbol clone = cloneTypeSymbolImpl(owner, attrs); - copyConstructorInfo(clone); - return clone; - } - - protected abstract TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs); -} - -public // !!! for java -Xfuture -final class AliasTypeSymbol extends TypeSymbol { - - /** Initializes this instance. */ - AliasTypeSymbol(Symbol owner, int pos, int flags, Name name, int attrs) { - super(ALIAS, owner, pos, flags, name, attrs); - } - - protected TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) { - return new AliasTypeSymbol(owner, pos, flags, name, attrs); - } - -} - -final class AbsTypeSymbol extends TypeSymbol { - - private Type lobound = null; - private Type vubound = null; - - /** Initializes this instance. */ - AbsTypeSymbol(Symbol owner, int pos, int flags, Name name, int attrs) { - super(TYPE, owner, pos, flags, name, attrs); - allConstructors().setInfo(Type.MethodType(EMPTY_ARRAY, Type.typeRef(owner.thisType(), this, Type.EMPTY_ARRAY))); - } - - public Type loBound() { - initialize(); - return lobound == null ? Global.instance.definitions.ALL_TYPE() : lobound; - } - - public Type vuBound() { - initialize(); - return !isViewBounded() || vubound == null - ? Global.instance.definitions.ANY_TYPE() : vubound; - } - - public Symbol setLoBound(Type lobound) { - this.lobound = lobound; - return this; - } - - public Symbol setVuBound(Type vubound) { - this.vubound = vubound; - return this; - } - - protected TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) { - TypeSymbol clone = new AbsTypeSymbol(owner, pos, flags, name, attrs); - clone.setLoBound(loBound()); - clone.setVuBound(vuBound()); - return clone; - } - -} - -/** A class for class symbols. */ -public class ClassSymbol extends TypeSymbol { - - /** The origin of this symbol */ - private SymbolOrigin origin; - - /** The given type of self, or NoType, if no explicit type was given. - */ - private Symbol thisSym = this; - - public Symbol thisSym() { return thisSym; } - - /** A cache for this.thisType() - */ - final private Type thistp = Type.ThisType(this); - - private final Symbol rebindSym; - - /** Initializes this instance. */ - ClassSymbol(Symbol owner, int pos, int flags, Name name, int attrs) { - super(CLASS, owner, pos, flags, name, attrs); - this.rebindSym = owner.newTypeAlias(pos, 0, Names.ALIAS(this)); - Type rebindType = new ClassAliasLazyType(); - this.rebindSym.setInfo(rebindType); - this.rebindSym.primaryConstructor().setInfo(rebindType); - } - - private class ClassAliasLazyType extends Type.LazyType { - public void complete(Symbol ignored) { - Symbol clasz = ClassSymbol.this; - Symbol alias = rebindSym; - Type prefix = clasz.owner().thisType(); - Type constrtype = clasz.type(); - constrtype = Type.MethodType(Symbol.EMPTY_ARRAY, constrtype); - constrtype = Type.PolyType(clasz.typeParams(), constrtype); - constrtype = constrtype.cloneType( - clasz.primaryConstructor(), alias.primaryConstructor()); - alias.primaryConstructor().setInfo(constrtype); - alias.setInfo(constrtype.resultType()); - } - } - - /** Creates the root class. */ - public static Symbol newRootClass(Global global) { - int pos = Position.NOPOS; - Name name = Names.ROOT.toTypeName(); - Symbol owner = Symbol.NONE; - int flags = JAVA | PACKAGE | FINAL; - int attrs = IS_ROOT; - Symbol clasz = new ClassSymbol(owner, pos, flags, name, attrs); - clasz.setInfo(global.getRootLoader()); - clasz.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clasz.typeConstructor())); - // !!! Type.MethodType(Symbol.EMPTY_ARRAY, clasz.thisType())); - return clasz; - } - - /** Creates the this-type symbol associated to this class. */ - private final Symbol newThisType() { - return newTerm(pos, SYNTHETIC, Names.this_, IS_THISTYPE); - } - - /** Returns the origin of this symbol. */ - public SymbolOrigin getOrigin() { - return origin != null ? origin : super.getOrigin(); - } - - /** Sets the origin of this symbol. */ - public void setOrigin(SymbolOrigin origin) { - this.origin = origin; - } - - public Type thisType() { - Global global = Global.instance; - if (global.currentPhase.id > global.PHASE.ERASURE.id()) return type(); - return thistp; - } - - public Type typeOfThis() { - return thisSym.type(); - } - - public Symbol setTypeOfThis(Type tp) { - thisSym = newThisType(); - thisSym.setInfo(tp); - return this; - } - - /** Return the next enclosing class */ - public Symbol enclClass() { - return this; - } - - public Symbol caseFieldAccessor(int index) { - assert (flags & CASE) != 0 : this; - Scope.SymbolIterator it = info().members().iterator(); - Symbol sym = null; - if ((flags & JAVA) == 0) { - for (int i = 0; i <= index; i++) { - do { - sym = it.next(); - } while (sym != NONE && sym.kind != VAL || !sym.hasParamAccessorFlag() || !sym.isMethod()); - } - //System.out.println(this + ", case field[" + index + "] = " + sym);//DEBUG - } else { - sym = it.next(); - while (sym != NONE && (sym.flags & SYNTHETIC) == 0) { - //System.out.println("skipping " + sym); - sym = it.next(); - } - for (int i = 0; i < index; i++) - sym = it.next(); - //System.out.println("field accessor = " + sym);//DEBUG - } - assert sym != null : this; - return sym.stableAlternative(); - } - - public final Symbol rebindSym() { - return rebindSym; - } - - public void reset(Type completer) { - super.reset(completer); - thisSym = this; - } - - protected final TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) { - assert !isModuleClass(): Debug.show(this); - ClassSymbol clone = new ClassSymbol(owner, pos, flags, name, attrs); - if (thisSym != this) clone.setTypeOfThis(new ClonedThisSymLazyType()); - return clone; - } - - private final class ClonedThisSymLazyType extends Type.LazyType { - - public Type fix(Type type, Symbol clasz, Symbol clone, Type.Map map) { - switch (type) { - case ThisType(_): - return type; - case SingleType(_, _): - return map.apply(type); - case TypeRef(Type prefix, Symbol symbol, Type[] args): - if (symbol == clasz) type = Type.typeRef(prefix, clone, args); - return map.apply(type); - default: - throw Debug.abortIllegalCase(type); - } - } - - public Type getTypeFor(Symbol symbol) { - Symbol clasz = ClassSymbol.this; - Symbol clone = symbol.owner(); - Type.Map map = - Type.getSubst(clasz.typeParams(), clone.typeParams()); - Type self = clasz.type(); - Type type = clasz.typeOfThis(); - switch (type) { - case CompoundType(Type[] parents1, Scope members): - assert members.isEmpty(): Debug.show(clasz, type); - int length = parents1.length; - Type[] parents2 = new Type[parents1.length]; - boolean has_self = false; - for (int i = 0; i < parents2.length; i++) { - if (self.isSameAs(parents1[i])) { - assert !has_self: Debug.show(clasz, clone, type,""+i); - parents2[i] = clone.type(); - has_self = true; - } else { - parents2[i] = fix(parents1[i], clasz, clone, map); - } - } - if (!has_self) { - parents2 = Type.cloneArray(parents2, 1); - parents2[parents2.length - 1] = clone.type(); - } - return Type.compoundTypeWithOwner(clone, parents2, members); - default: - if (self.isSameAs(type)) return clone.type(); - Type[] parents = {fix(type, clasz, clone, map), clone.type()}; - return Type.compoundTypeWithOwner(clone, parents, new Scope()); - } - } - - public void complete(Symbol symbol) { - symbol.setInfo(getTypeFor(symbol)); - } - - } - -} - -/** - * A class for module class symbols - * - * @see Symbol#sourceModule() - */ -public final class ModuleClassSymbol extends ClassSymbol { - - /** The source module */ - private final ModuleSymbol module; - - /** Initializes this instance. */ - ModuleClassSymbol(ModuleSymbol module) { - super(module.owner(), module.pos, - (module.flags & MODULE2CLASSFLAGS) | MODUL | FINAL, - module.name.toTypeName(), 0); - primaryConstructor().flags |= PRIVATE; - primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, typeConstructor())); - this.module = module; - } - - public ModuleSymbol sourceModule() { - return module; - } - -} - -/** - * A class for linked class symbols - * - * @see Symbol#linkedModule() - */ -public // !!! for java -Xfuture -final class LinkedClassSymbol extends ClassSymbol { - - /** The linked module */ - private final LinkedModuleSymbol module; - - /** Initializes this instance. */ - LinkedClassSymbol(Symbol owner, int flags, Name name) { - super(owner, Position.NOPOS, flags, name, 0); - this.module = new LinkedModuleSymbol(this); - } - - public ModuleSymbol linkedModule() { - return module; - } - -} - -/** The class of Symbol.NONE - */ -public // !!! for java -Xfuture -final class NoSymbol extends Symbol { - - /** Constructor */ - public NoSymbol() { - super(Kinds.NONE, null, Position.NOPOS, 0, Names.NOSYMBOL, 0); - super.setInfo(Type.NoType); - } - - /** Returns the origin of this symbol. */ - public SymbolOrigin getOrigin() { - return SymbolOrigin.Unknown; - } - - /** Set type */ - public Symbol setInfo(Type info) { - assert info == Type.NoType : info; - return this; - } - - /** Return the next enclosing class */ - public Symbol enclClass() { - return this; - } - - /** Return the next enclosing method */ - public Symbol enclMethod() { - return this; - } - - public Symbol owner() { - throw new ApplicationError(); - } - - public Type thisType() { - return Type.NoPrefix; - } - - public void reset(Type completer) { - } - - protected Symbol cloneSymbolImpl(Symbol owner, int attrs) { - throw Debug.abort("illegal clone", this); - } - -} - -/** An exception for signalling cyclic references. - */ -public class CyclicReference extends Type.Error { - public Symbol sym; - public Type info; - public CyclicReference(Symbol sym, Type info) { - super("illegal cyclic reference involving " + sym); - this.sym = sym; - this.info = info; - } -} - -/** A base class for values indexed by phases. */ -public // !!! for java -Xfuture -abstract class IntervalList { - - /** Interval starts at start of phase "start" (inclusive) */ - public final Phase start; - /** Interval ends at start of phase "limit" (inclusive) */ - private Phase limit; - - public IntervalList(IntervalList prev, Phase start) { - this.start = start; - this.limit = start; - assert start != null && (prev == null || prev.limit.next == start) : - Global.instance.currentPhase + " - " + prev + " - " + start; - } - - public Phase limit() { - return limit; - } - - public void setLimit(Phase phase) { - assert phase != null && !phase.precedes(start) : start + " - " + phase; - limit = phase; - } - - public String toString() { - return "[" + start + "->" + limit + "]"; - } - -} - -/** A class for types indexed by phases. */ -public // !!! for java -Xfuture -class TypeIntervalList extends IntervalList { - - /** Previous interval */ - public final TypeIntervalList prev; - /** Info valid during this interval */ - public final Type info; - - public TypeIntervalList(TypeIntervalList prev, Type info, Phase start) { - super(prev, start); - this.prev = prev; - this.info = info; - assert info != null; - } - -} diff --git a/sources/scalac/symtab/SymbolCloner.java b/sources/scalac/symtab/SymbolCloner.java deleted file mode 100644 index d07717bdc7..0000000000 --- a/sources/scalac/symtab/SymbolCloner.java +++ /dev/null @@ -1,243 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.util.HashMap; -import java.util.Map; - -import scalac.util.Debug; - -/** - * This class implements a symbol cloner. It automatically determines - * the new owner of cloned symbols, clones their type and keeps track - * of all cloned symbols. Clone a type means clone all symbol declared - * in that type (for example parameters of a MethodType). - */ -public class SymbolCloner { - - //######################################################################## - // Public Fields - - /** A table that maps owners of symbols to owners of cloned symbols */ - public final Map/*<Symbol,Symbol*/ owners; - - /** A map<cloned,clone> into which cloned symbols are stored */ - public final Map/*<Symbol,Symbol*/ clones; - - //######################################################################## - // Public Constructor - - /** Initializes a new instance. */ - public SymbolCloner() { - this(new HashMap()); - } - - /** Initializes a new instance. */ - public SymbolCloner(Map owners) { - this(owners, new HashMap()); - } - - /** Initializes a new instance. */ - public SymbolCloner(Map owners, Map clones) { - this.owners = owners; - this.clones = clones; - } - - //######################################################################## - // Public Methods - Cloning symbols - - /** - * Returns the owner for the clone of the given symbol. The - * default implementation returns the clone of the symbol's owner - * if that owner has been cloned or else returns the owner - * associated to the symbol's owner in the owner table. - */ - public Symbol getOwnerFor(Symbol symbol) { - Symbol oldowner = symbol.owner(); - Object newowner = clones.get(oldowner); - if (newowner == null) newowner = owners.get(oldowner); - assert newowner != null : Debug.show(symbol); - return (Symbol)newowner; - } - - /** Clones the given symbol but not its type. */ - public Symbol cloneSymbolWithoutType(Symbol symbol) { - assert !symbol.isPrimaryConstructor(): Debug.show(symbol); - assert !symbol.isClassType() || symbol.isCompoundSym(): Debug.show(symbol); // !!! isCompoundSym() - assert !owners.containsKey(symbol): Debug.show(symbol); - assert !clones.containsKey(symbol): - Debug.show(symbol) + " -> " + Debug.show(clones.get(symbol)); - Symbol clone = symbol.cloneSymbol(getOwnerFor(symbol)); - clones.put(symbol, clone); - return clone; - } - - /** Clones the given symbols but not their types. */ - public Symbol[] cloneSymbolsWithoutTypes(Symbol[] symbols) { - if (symbols.length == 0) return Symbol.EMPTY_ARRAY; - Symbol[] clones = new Symbol[symbols.length]; - for (int i = 0; i < clones.length; i++) - clones[i] = cloneSymbolWithoutType(symbols[i]); - return clones; - } - - /** Clones the given scope but not the type of its members. */ - public Scope cloneScopeWithoutTypes(Scope scope) { - Scope clone = new Scope(); - for (Scope.SymbolIterator i = scope.iterator(); - i.hasNext(); ) { - clone.enterOrOverload(cloneSymbolWithoutType(i.next())); - } - return clone; - } - - /** Clones the given symbol and its type. */ - public Symbol cloneSymbol(Symbol symbol) { - Symbol clone = cloneSymbolWithoutType(symbol); - clone.setType(cloneType(symbol.info())); - return clone; - } - - /** Clones the given symbols and their types. */ - public Symbol[] cloneSymbols(Symbol[] symbols) { - Symbol[] clones = cloneSymbolsWithoutTypes(symbols); - for (int i = 0; i < clones.length; i++) - clones[i].setType(cloneType(symbols[i].info())); - return clones; - } - - /** Clones the given scope and the type of its members. */ - public Scope cloneScope(Scope scope) { - Scope clone = cloneScopeWithoutTypes(scope); - for (Scope.SymbolIterator i = scope.iterator(); - i.hasNext(); ) { - Symbol member = i.next(); - member.setType(cloneType(member.info())); - } - return clone; - } - - /** Clones the given type. */ - public Type cloneType(Type type) { - return cloner.apply(type); - } - - /** Clones the given types. */ - public Type[] cloneTypes(Type[] types) { - Type[] clones = new Type[types.length]; - for (int i = 0; i < types.length; i++) - clones[i] = cloner.apply(types[i]); - return clones; - } - - //######################################################################## - // Public Methods - Mapping symbols - - /** - * Returns the clone of the specified symbol if it has been cloned - * and the specified symbol otherwise. - */ - public Symbol mapSymbol(Symbol symbol) { - Object clone = clones.get(symbol); - return clone != null ? (Symbol)clone : symbol; - } - - /** Replaces all cloned symbols by clones in given type. */ - public Type mapType(Type type) { - return mapper.apply(type); - } - - /** Returns the type map built during symbol cloning. */ - // used in scalac/ast/TreeCloner.java - public Type.Map getTypeMap() { - return cloner; - } - - //######################################################################## - // Private Method - - private Symbol getCompoundClone(Symbol symbol) { - assert symbol.isCompoundSym(): Debug.show(symbol); - assert !owners.containsKey(symbol): Debug.show(symbol); - assert !clones.containsKey(symbol): - Debug.show(symbol) + " -> " + Debug.show(clones.get(symbol)); - Symbol owner = (Symbol)clones.get(symbol.owner()); - if (owner == null) owner = (Symbol)owners.get(symbol.owner()); - if (owner == null) owner = symbol.owner(); - Symbol clone = symbol.cloneSymbol(owner); - clones.put(symbol, clone); - return clone; - } - - //######################################################################## - // Private Class - Type mapper - - /** The type mapper Type.Map */ - private final Type.Map mapper = new TypeMapper(); - private class TypeMapper extends Type.Map { public Type apply(Type type) { - switch (type) { - case ErrorType: - case NoType: - case NoPrefix: - return type; - case ThisType(Symbol symbol): - Symbol clone = (Symbol)clones.get(symbol); - if (clone == null) return type; - return Type.ThisType(clone); - case SingleType(Type prefix, Symbol symbol): - Symbol clone = (Symbol)clones.get(symbol); - if (clone == null) return map(type); - return Type.singleType(apply(prefix), clone); - case ConstantType(_, _): - return map(type); - case TypeRef(Type prefix, Symbol symbol, Type[] args): - Symbol clone = (Symbol)clones.get(symbol); - if (clone == null) return map(type); - return Type.typeRef(apply(prefix), clone, map(args)); - case CompoundType(Type[] parts, Scope members): - Symbol clone = (Symbol)clones.get(type.symbol()); - // !!! if (clone == null) return map(type); - if (clone == null) clone = type.symbol(); - return Type.compoundType(map(parts), members, clone); - case MethodType(Symbol[] vparams, Type result): - return Type.MethodType(vparams, apply(result)); - case PolyType(Symbol[] tparams, Type result): - return Type.PolyType(tparams, apply(result)); - case UnboxedType(_): - return type; - case UnboxedArrayType(_): - return map(type); - default: - throw Debug.abort("illegal case", type); - } - }} - - //######################################################################## - // Private Class - Type cloner - - /** The type cloner Type.Map */ - private final Type.Map cloner = new TypeCloner(); - private class TypeCloner extends TypeMapper { public Type apply(Type type){ - switch (type) { - case CompoundType(Type[] parts, Scope members): - Symbol clone = /* !!! getCompoundClone */(type.symbol()); - return Type.compoundType(map(parts), /* !!! cloneScope */(members), clone); - case MethodType(Symbol[] vparams, Type result): - Symbol[] clones = cloneSymbols(vparams); - return Type.MethodType(clones, apply(result)); - case PolyType(Symbol[] tparams, Type result): - Symbol[] clones = cloneSymbols(tparams); - return Type.PolyType(clones, apply(result)); - default: - return super.apply(type); - } - }} - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolComparator.java b/sources/scalac/symtab/SymbolComparator.java deleted file mode 100644 index c703663bf4..0000000000 --- a/sources/scalac/symtab/SymbolComparator.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.util.Comparator; - -/** This class implements a symbol comparator. */ -public class SymbolComparator implements Comparator { - - //######################################################################## - // Public Constants - - /** The unique instance of this class */ - public static final Comparator instance = new SymbolComparator(); - - //######################################################################## - // Private Constructors - - /** Initializes this instance. */ - private SymbolComparator() {} - - //######################################################################## - // Public Methods - - /** Compares the two arguments which must inherit from Symbol. */ - public int compare(Object lf, Object rg) { - return lf == rg ? 0 : ((Symbol)lf).isLess((Symbol)rg) ? -1 : 1; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolLoader.java b/sources/scalac/symtab/SymbolLoader.java deleted file mode 100644 index 2f656c92e0..0000000000 --- a/sources/scalac/symtab/SymbolLoader.java +++ /dev/null @@ -1,168 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.io.IOException; - -import scalac.Global; -import scalac.Phase; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This class implements common behaviors of lazy types used to load - * symbols from external sources (containing source or compiled code). - */ -public abstract class SymbolLoader extends Type.LazyType { - - //######################################################################## - // Public Fields - - /** The global environment */ - public final Global global; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public SymbolLoader(Global global) { - this.global = global; - } - - //######################################################################## - // Public Methods - - /** - * Completes the specified symbol. More precisely, it completes - * all symbols related to the root symbol of the specified - * symbol. It is guaranteed that after this method call all these - * symbols are initialized (or at least that their info does no - * longer contain this lazy type). - * - * The root symbol of a symbol is: - * - the root symbol of the constructed class, if it's a - * constructor, - * - the root symbol of the source module, if it's a module class, - * - the linked class, if it's a module with a linked class, - * - itself if it's a class or a module with no linked class, - * - undefined otherwise. - * - * The symbols related to a symbol include: - * - the symbol itself, - * - its constructor (allConstructors()), if it's a class, - * - the symbols related to its linked module, if there is one. - * - the symbols related to its module class, if it's a module, - */ - public final void complete(Symbol symbol) { - Symbol root = getRootSymbol(symbol); - try { - Phase phase = global.currentPhase; - global.currentPhase = global.PHASE.ANALYZER.phase(); - global.timer.start(); - String source = doComplete(root); - global.timer.stop("loaded " + source); - global.currentPhase = phase; - checkValidity(root, source); - } catch (IOException exception) { - global.timer.drop(); - if (global.debug) exception.printStackTrace(); - String error = "error while loading " + symbol; - String message = exception.getMessage(); - error = message != null ? error + ", " + message : "i/o " + error; - global.error(error); - } - initializeRoot(root); - } - - //######################################################################## - // Protected Methods - - /** - * Performs the actual loading and returns the name of the - * external source. It is guaranteed that the argument of this - * method is always a root symbol - * - * @see complete(Symbol) - */ - protected abstract String doComplete(Symbol root) throws IOException; - - //######################################################################## - // Private Methods - - /** - * Returns the root symbol of the specified symbol. - * - * @see complete(Symbol) - */ - private Symbol getRootSymbol(Symbol symbol) { - if (symbol.isConstructor()) - return getRootSymbol(symbol.constructorClass()); - if (symbol.isModuleClass()) - return getRootSymbol(symbol.sourceModule()); - if (symbol.isModule() && symbol.linkedClass() != null) - return symbol.linkedClass(); - assert symbol.isClassType() || symbol.isModule(): Debug.show(symbol); - return symbol; - } - - /** - * Checks that at least the specified root symbol or its linked - * module, if any, has been initialized and signals an error - * otherwise. - * - * @see complete(Symbol) - */ - private void checkValidity(Symbol root, String source) { - if (root.rawInfo() != this) return; - String what; - if (!root.isClassType() || root.linkedModule() == null) { - what = "does not define " + root; - } else { - if (root.linkedModule().moduleClass().rawInfo() != this) return; - what = "defines neither " + root + " nor " + root.linkedModule(); - } - global.error(source + " " + what); - } - - /** - * Initializes all symbols related to the specified root symbol - * and whose info is this instance. - * - * @see complete(Symbol) - */ - private void initializeRoot(Symbol root) { - if (root.isClassType()) { - initializeClass(root); - if (root.linkedModule() != null) - initializeRoot(root.linkedModule()); - } else { - initializeSymbol(root); - if (root.isModule()) initializeClass(root.moduleClass()); - } - } - - /** - * Initializes the specified class and its constructor if their - * info is this instance. - */ - private void initializeClass(Symbol clasz) { - initializeSymbol(clasz); - initializeSymbol(clasz.allConstructors()); - } - - /** Initializes the symbol if its info is this instance. */ - private void initializeSymbol(Symbol symbol) { - if (symbol.rawInfo() != this) return; - symbol.setInfo(symbol.isModule() ? Type.NoType : Type.ErrorType); - if (symbol.isConstructor()) symbol.flags |= Modifiers.PRIVATE; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolNameWriter.java b/sources/scalac/symtab/SymbolNameWriter.java deleted file mode 100644 index af57b23933..0000000000 --- a/sources/scalac/symtab/SymbolNameWriter.java +++ /dev/null @@ -1,306 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import scalac.Global; -import scalac.util.NameTransformer; - -/** - * This class provides methods to turn symbol names into strings. - * - * There are several kinds of owner/symbol relationships: - * - root/symbol - * - package/symbol - * - class/class - * - class/member - * - owner/parameter - * - none/symbol - * - error/symbol - * - other relationships - * - * The separator to use for each of these relationships are specified - * independently. When a separator is set to '\0' the corresponding - * owners are dropped from the resulting string. ROOT, NONE and ERROR - * owners are also dropped. The choice of the separator to use is done - * by the method "getOwnerSymbolSeparator(Symbol)" - * - * Symbol names are usually encoded. There is support to decode these - * names. - * - * Each symbol has an unique identifier. There is support to print - * these unique identifiers. - */ -public class SymbolNameWriter { - - //######################################################################## - // Private Fields - - /** The string buffer */ - private StringBuffer buffer; - - /** The root/symbol separator */ - private char root; - - /** The package/symbol separator */ - private char peckage; - - /** The class/class separator */ - private char clasz; - - /** The class/member separator */ - private char member; - - /** The owner/parameter separator */ - private char parameter; - - /** The none/symbol separator */ - private char none; - - /** The error/symbol separator */ - private char error; - - /** The other relationships separator */ - private char other; - - /** The name decoding status */ - private boolean decode; - - /** The symbol/unique-identifier separator */ - private char unique; - - /** The number of pending characters */ - private int pending; - - /** The prefix for the current operation (null if none) */ - private String prefix; - - //######################################################################## - // Public Constructors - - /** - * Initializes this instance with an empty string buffer. This is - * equivalent to calling "SymbolStringifier(null)". - */ - public SymbolNameWriter() { - this(null); - } - - /** - * Initializes this instance with given string buffer. All - * separators are set to '.' excepted the root/symbol separator - * which is set to '\0'. The symbol name decoding is disabled. The - * unique identifier printing is disabled. - */ - public SymbolNameWriter(StringBuffer buffer) { - setStringBuffer(buffer).setAllSeparators('.').setRootSeparator('\0'); - } - - //######################################################################## - // Public Method - Configuration operations - - /** Sets the string buffer. */ - public SymbolNameWriter setStringBuffer(StringBuffer buffer) { - this.buffer = buffer; - return this; - } - - /** Sets all separators. */ - public SymbolNameWriter setAllSeparators(char separator) { - setRootSeparator(separator); - setPackageSeparator(separator); - setClassSeparator(separator); - setMemberSeparator(separator); - setParameterSeparator(separator); - setNoneSeparator(separator); - setErrorSeparator(separator); - setOtherSeparator(separator); - return this; - } - - /** Sets the root/symbol separator. */ - public SymbolNameWriter setRootSeparator(char separator) { - this.root = separator; - return this; - } - - /** Sets the package/symbol separator. */ - public SymbolNameWriter setPackageSeparator(char separator) { - this.peckage = separator; - return this; - } - - /** Sets the class/class separator. */ - public SymbolNameWriter setClassSeparator(char separator) { - this.clasz = separator; - return this; - } - - /** Sets the class/member separator. */ - public SymbolNameWriter setMemberSeparator(char separator) { - this.member = separator; - return this; - } - - /** Sets the owner/parameter separator. */ - public SymbolNameWriter setParameterSeparator(char separator) { - this.parameter = separator; - return this; - } - - /** Sets the none/symbol separator. */ - public SymbolNameWriter setNoneSeparator(char separator) { - this.none = separator; - return this; - } - - /** Sets the error/symbol separator. */ - public SymbolNameWriter setErrorSeparator(char separator) { - this.error = separator; - return this; - } - - /** Sets the other relationships separator. */ - public SymbolNameWriter setOtherSeparator(char separator) { - this.other = separator; - return this; - } - - /** Sets the name decoding status. */ - public SymbolNameWriter setNameDecoding(boolean decode) { - this.decode = decode; - return this; - } - - /** Sets the symbol/unique-identifier separator. */ - public SymbolNameWriter setUniqueSeparator(char separator) { - this.unique = separator; - return this; - } - - //######################################################################## - // Public Method - To string operations - - /** Returns the string formed by the symbol. */ - public String toString(Symbol symbol) { - assert buffer == null; - String string = appendSymbol(symbol).toString(); - setStringBuffer(null); - return string; - } - - /** Returns the string formed by the prefix and symbol. */ - public String toString(String prefix, Symbol symbol) { - assert buffer == null; - String string = appendSymbol(prefix, symbol).toString(); - setStringBuffer(null); - return string; - } - - /** Returns the string formed by the symbol and suffix. */ - public String toString(Symbol symbol, String suffix) { - assert buffer == null; - String string = appendSymbol(symbol, suffix).toString(); - setStringBuffer(null); - return string; - } - - /** Returns the string formed by the prefix, symbol and suffix. */ - public String toString(String prefix, Symbol symbol, String suffix) { - assert buffer == null; - String string = appendSymbol(prefix, symbol, suffix).toString(); - setStringBuffer(null); - return string; - } - - //######################################################################## - // Public Method - Append operations - - /** Appends given symbol. */ - public StringBuffer appendSymbol(Symbol symbol) { - String name = getSymbolName(symbol); - this.pending += name.length(); - char separator = getSymbolSeparator(symbol); - return appendPrefix(symbol.owner(), separator).append(name);; - } - - /** Appends given prefix and symbol. */ - public StringBuffer appendSymbol(String prefix, Symbol symbol) { - assert this.prefix == null && prefix != null; - this.prefix = prefix; - return appendSymbol(symbol); - } - - /** Appends given symbol and suffix. */ - public StringBuffer appendSymbol(Symbol symbol, String suffix) { - this.pending += suffix.length(); - return appendSymbol(symbol).append(suffix); - } - - /** Appends given prefix, symbol and suffix. */ - public StringBuffer appendSymbol(String prefix, Symbol symbol, - String suffix) - { - assert this.prefix == null && prefix != null; - this.prefix = prefix; - this.pending += suffix.length(); - return appendSymbol(symbol).append(suffix); - } - - /** Appends prefix formed by given owner and separator. */ - public StringBuffer appendPrefix(Symbol owner, char separator) { - if (separator == 0) return getStringBuffer(); - this.pending += 1; - return appendSymbol(owner).append(separator); - } - - //######################################################################## - // Public Method - Query operations - - /** Returns the name to use for given symbol. */ - public String getSymbolName(Symbol symbol) { - String name = symbol.name.toString(); - if (decode) name = NameTransformer.decode(name); - if (unique != 0) name = name + unique + symbol.id; - return name; - } - - /** Returns the owner/symbol separator to use for given symbol. */ - public char getSymbolSeparator(Symbol symbol) { - if (symbol.isRoot() || symbol.isNone() || symbol.isError()) return 0; - if (symbol.isParameter()) return parameter; - Symbol owner = symbol.owner(); - if (owner.isRoot()) return root; - if (owner.isNone()) return none; - if (owner.isError()) return error; - if (owner.isPackageClass()) return peckage; - if (owner.isClass()) return symbol.isClass() ? clasz : member; - return other; - } - - /** Returns the string buffer. */ - public StringBuffer getStringBuffer() { - if (prefix != null) pending += prefix.length(); - if (buffer == null) { - this.buffer = new StringBuffer(pending); - } else { - buffer.ensureCapacity(buffer.length() + pending); - } - if (prefix != null) buffer.append(prefix); - this.pending = 0; - this.prefix = null; - return buffer; - } - - /** Returns the content of the string buffer. */ - public String toString() { - return buffer == null ? "" : buffer.toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolOrigin.java b/sources/scalac/symtab/SymbolOrigin.java deleted file mode 100644 index 29baa08a79..0000000000 --- a/sources/scalac/symtab/SymbolOrigin.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import ch.epfl.lamp.compiler.msil.Assembly; -import scala.tools.util.AbstractFile; -import scalac.CompilationUnit; - -/** Instances of this class designate the origin of a symbol. */ -public class SymbolOrigin { - - //######################################################################## - // Public Cases - - /** Designates an unknown source */ - public case Unknown; - - /** Designates a directory */ - public case Directory(AbstractFile file); - - /** Designates a JVM class file (the source file may be null) */ - public case ClassFile(AbstractFile file, String sourcefile); - - /** Designates a Scala symbl file */ - public case SymblFile(AbstractFile file); - - /** Designates a Scala source file */ - public case ScalaFile(AbstractFile file); - - /** Designates a Scala compilation unit */ - public case ScalaUnit(CompilationUnit unit); - - /** Designates a CLR assembly */ - public case CLRAssembly(Assembly assembly); - - //######################################################################## - // Public Methods - - /** Records the source file attribute. */ - public void setSourceFileAttribute(String sourcefile) { - if (this instanceof SymbolOrigin.ClassFile) - ((SymbolOrigin.ClassFile)this).sourcefile = sourcefile; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolSubstTypeMap.java b/sources/scalac/symtab/SymbolSubstTypeMap.java deleted file mode 100644 index 144181faac..0000000000 --- a/sources/scalac/symtab/SymbolSubstTypeMap.java +++ /dev/null @@ -1,199 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; - -import ch.epfl.lamp.util.ForwardingMap; - -import scalac.util.Debug; - -/** A type map that substitues symbols and types for symbols. */ -public class SymbolSubstTypeMap extends Type.Map { - - //######################################################################## - // Private Fields - - /** A table containing the symbol to symbol substitutions */ - private Map/*<Symbol, Symbol>*/ symbols; - - /** A table containing the symbol to type substitutions */ - private Map/*<Symbol, Type>*/ types; - - //######################################################################## - // Public Constructors - - public SymbolSubstTypeMap() { - this.symbols = new HashMap(); - this.types = new HashMap(); - } - - public SymbolSubstTypeMap(Map symbols, Map types) { - this(); - insertSymbol(symbols); - insertType(types); - } - - public SymbolSubstTypeMap(SymbolSubstTypeMap other) { - this(); - insertSymbol(other.symbols); - insertType(other.types); - } - - //######################################################################## - // Public Methods - Inserting and removing symbol to symbol substitutions - - public void insertSymbol(Symbol[] keys, Symbol[] values) { - assert keys.length == values.length : keys.length+" != "+values.length; - for (int i = 0; i < keys.length; i++) insertSymbol(keys[i], values[i]); - } - - public void insertSymbol(Symbol key, Symbol value) { - assert !symbols.containsKey(key) : Debug.show(key); - assert !types.containsKey(key) : Debug.show(key); - symbols.put(key, value); - } - - public void insertSymbol(Map map) { - assert checkLeftContainsNoKeyFromRight(symbols, map); - assert checkLeftContainsNoKeyFromRight(types, map); - symbols.putAll(map); - } - - public void removeSymbol(Symbol[] keys) { - for (int i = 0; i < keys.length; i++) removeSymbol(keys[i]); - } - - public void removeSymbol(Symbol key) { - symbols.remove(key); - } - - public void removeSymbol(Set keys) { - symbols.keySet().removeAll(keys); - } - - public Symbol lookupSymbol(Symbol key) { - return (Symbol)symbols.get(key); - } - - public Map getSymbols() { - return new ForwardingMap(symbols) { - public Object put(Object key, Object value) { - insertSymbol((Symbol)key, (Symbol)value); - return null; - } - public void putAll(Map map) { - insertSymbol(map); - } - }; - } - - //######################################################################## - // Public Methods - Inserting and removing symbol to type substitutions - - public void insertType(Symbol[] keys, Type[] values) { - assert keys.length == values.length : keys.length+" != "+values.length; - for (int i = 0; i < keys.length; i++) insertType(keys[i], values[i]); - } - - public void insertType(Symbol key, Type value) { - assert !symbols.containsKey(key) : Debug.show(key); - assert !types.containsKey(key) : Debug.show(key); - types.put(key, value); - } - - public void insertType(Map map) { - assert checkLeftContainsNoKeyFromRight(symbols, map); - assert checkLeftContainsNoKeyFromRight(types, map); - types.putAll(map); - } - - public void removeType(Symbol[] keys) { - for (int i = 0; i < keys.length; i++) removeType(keys[i]); - } - - public void removeType(Symbol key) { - types.remove(key); - } - - public void removeType(Set keys) { - types.keySet().removeAll(keys); - } - - public Type lookupType(Symbol key) { - return (Type)types.get(key); - } - - public Map getTypes() { - return new ForwardingMap(types) { - public Object put(Object key, Object value) { - insertType((Symbol)key, (Type)value); - return null; - } - public void putAll(Map map) { - insertType(map); - } - }; - } - - //######################################################################## - // Public Methods - Applying the substitutions - - public Type apply(Type type) { - switch (type) { - - case TypeRef(NoPrefix, Symbol symbol, Type[] args): - Object value = types.get(symbol); - if (value != null) return (Type)value; - value = symbols.get(symbol); - if (value == null) return super.map(type); - Type prefix = ((Type.TypeRef)type).pre; - return Type.typeRef(apply(prefix), (Symbol)value, map(args)); - - case SingleType(NoPrefix, Symbol symbol): - Object value = types.get(symbol); - if (value != null) return (Type)value; - value = symbols.get(symbol); - if (value == null) return super.map(type); - Type prefix = ((Type.SingleType)type).pre; - return Type.singleType(apply(prefix), (Symbol)value); - - case ThisType(Symbol symbol): - Object value = symbols.get(symbol); - if (value == null) return super.map(type); - return Type.ThisType((Symbol)value); - - default: - return super.map(type); - } - } - - //######################################################################## - // Public Methods - Printing - - public String toString() { - return "{ symbols=" + symbols + " types=" + types + " }"; - } - - //######################################################################## - // Private Function - - private static boolean checkLeftContainsNoKeyFromRight(Map lf, Map rg) { - for (Iterator i = rg.keySet().iterator(); i.hasNext(); ) { - Object key = i.next(); - assert !lf.containsKey(key) : Debug.show(key); - } - return true; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolTablePrinter.java b/sources/scalac/symtab/SymbolTablePrinter.java deleted file mode 100644 index ad6fdbf1cd..0000000000 --- a/sources/scalac/symtab/SymbolTablePrinter.java +++ /dev/null @@ -1,602 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.io.StringWriter; - -import ch.epfl.lamp.util.CodePrinter; - -import scalac.Global; -import scalac.atree.AConstant; -import scalac.symtab.Type.Constraint; -import scalac.symtab.Scope.SymbolIterator; -import scalac.util.Name; -import scalac.util.NameTransformer; -import scalac.util.Debug; - -/** This class provides methods to print symbols and types. */ -public class SymbolTablePrinter { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The underlying code printer */ - private final CodePrinter printer; - - //######################################################################## - // Public Constructors - - /** Creates a new instance */ - public SymbolTablePrinter() { - this((String)null); - } - - /** Creates a new instance */ - public SymbolTablePrinter(String step) { - this(Global.instance, new CodePrinter(step)); - } - - /** Creates a new instance */ - public SymbolTablePrinter(CodePrinter printer) { - this(Global.instance, printer); - } - - /** Creates a new instance */ - public SymbolTablePrinter(Global global, CodePrinter printer) { - this.global = global; - this.printer = printer; - } - - //######################################################################## - // Public Methods - Getting & Setting - - /** Returns the underlying code printer. */ - public CodePrinter getCodePrinter() { - return printer; - } - - //######################################################################## - // Public Methods - Formatting - - /** Increases the indentation level by one. */ - public SymbolTablePrinter indent() { - printer.indent(); - return this; - } - - /** Decreases the indentation level by one. */ - public SymbolTablePrinter undent() { - printer.undent(); - return this; - } - - /** Inserts a new line. */ - public SymbolTablePrinter line() { - printer.line(); - return this; - } - - /** Inserts a white space. */ - public SymbolTablePrinter space() { - printer.space(); - return this; - } - - //######################################################################## - // Public Methods - Printing simple values - - /** Prints a new line. */ - public SymbolTablePrinter println() { - printer.println(); - return this; - } - - /** Prints the boolean value followed by a new line. */ - public SymbolTablePrinter println(boolean value) { - printer.println(value); - return this; - } - - /** Prints the byte value followed by a new line. */ - public SymbolTablePrinter println(byte value) { - printer.println(value); - return this; - } - - /** Prints the short value followed by a new line. */ - public SymbolTablePrinter println(short value) { - printer.println(value); - return this; - } - - /** Prints the char value followed by a new line. */ - public SymbolTablePrinter println(char value) { - printer.println(value); - return this; - } - - /** Prints the int value followed by a new line. */ - public SymbolTablePrinter println(int value) { - printer.println(value); - return this; - } - - /** Prints the long value followed by a new line. */ - public SymbolTablePrinter println(long value) { - printer.println(value); - return this; - } - - /** Prints the float value followed by a new line. */ - public SymbolTablePrinter println(float value) { - printer.println(value); - return this; - } - - /** Prints the double value followed by a new line. */ - public SymbolTablePrinter println(double value) { - printer.println(value); - return this; - } - - /** Prints the string followed by a new line. */ - public SymbolTablePrinter println(String value) { - printer.println(value); - return this; - } - - /** Prints the boolean value. */ - public SymbolTablePrinter print(boolean value) { - printer.print(value); - return this; - } - - /** Prints the byte value. */ - public SymbolTablePrinter print(byte value) { - printer.print(value); - return this; - } - - /** Prints the short value. */ - public SymbolTablePrinter print(short value) { - printer.print(value); - return this; - } - - /** Prints the char value. */ - public SymbolTablePrinter print(char value) { - printer.print(value); - return this; - } - - /** Prints the int value. */ - public SymbolTablePrinter print(int value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public SymbolTablePrinter print(long value) { - printer.print(value); - return this; - } - - /** Prints the float value. */ - public SymbolTablePrinter print(float value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public SymbolTablePrinter print(double value) { - printer.print(value); - return this; - } - - /** Prints the string. */ - public SymbolTablePrinter print(String value) { - printer.print(value); - return this; - } - - //######################################################################## - // Public Methods - Printing scopes - - /** Prints the members of the given scope. */ - public SymbolTablePrinter printScope(Scope scope) { - return printScope(scope, false); - } - - /** Prints the members of the given scope. */ - public SymbolTablePrinter printScope(Scope scope, boolean lazy) { - boolean first = true; - for (SymbolIterator i = scope.iterator(); i.hasNext(); ) { - Symbol member = i.next(); - if (!mustShowMember(member)) continue; - if (first) print("{").indent(); else print(", "); - first = false; - line().printSignature(member); - } - if (!first) line().undent().print("}"); else if (!lazy) print("{}"); - return this; - } - - /** - * Returns true iff the given member must be printed. The default - * implementation always returns true. - */ - public boolean mustShowMember(Symbol member) { - return true; - } - - //######################################################################## - // Public Methods - Printing symbols - - /** - * Returns the string representation of the kind of the given - * symbol or null if there is no such representation. - */ - public String getSymbolKind(Symbol symbol) { - switch (symbol.kind) { - case Kinds.NONE: - return null; - case Kinds.CLASS: - if (symbol.isPackageClass()) return "package class"; - if (symbol.isModuleClass()) return "object class"; - if (symbol.isTrait()) return "trait"; - return "class"; - case Kinds.TYPE: - case Kinds.ALIAS: - return "type"; - case Kinds.VAL: - if (symbol.isVariable()) return "variable"; - if (symbol.isPackage()) return "package"; - if (symbol.isModule()) return "object"; - if (symbol.isConstructor()) return "constructor"; - if (symbol.isInitializedMethod()) - if (global.debug || (symbol.flags & Modifiers.STABLE) == 0) - return "method"; - return "value"; - default: - throw Debug.abort("unknown kind " + symbol.kind); - } - } - - /** - * Returns the definition keyword associated to the given symbol - * or null if there is no such keyword. - */ - public String getSymbolKeyword(Symbol symbol) { - if (symbol.isParameter()) return null; - switch (symbol.kind) { - case Kinds.NONE: - return null; - case Kinds.CLASS: - if (symbol.isTrait()) return "trait"; - return "class"; - case Kinds.TYPE: - case Kinds.ALIAS: - return "type"; - case Kinds.VAL: - if (symbol.isVariable()) return "var"; - if (symbol.isPackage()) return "package"; - if (symbol.isModule()) return "object"; - if (symbol.isInitializedMethod()) return "def"; - return "val"; - default: - throw Debug.abort("unknown kind " + symbol.kind); - } - } - - /** Returns the name of the given symbol. */ - public String getSymbolName(Symbol symbol) { - String name = symbol.simpleName().toString(); - if (!global.debug) name = NameTransformer.decode(name); - return name; - } - - /** Returns the inner string of the given symbol. */ - public String getSymbolInnerString(Symbol symbol) { - switch (symbol.kind) { - case Kinds.NONE : return ": "; - case Kinds.ALIAS: return " = "; - case Kinds.CLASS: return " extends "; - case Kinds.TYPE : return " <: "; - case Kinds.VAL : return symbol.isModule() ? " extends " : - symbol.isDefParameter() ? ": => " : ": "; - default : throw Debug.abort("unknown kind " + symbol.kind); - } - } - - /** Prints the unique identifier of the given symbol */ - public SymbolTablePrinter printSymbolUniqueId(Symbol symbol) { - if (global.uniqid) print('#').print(symbol.id); - return this; - } - - /** Prints the name of the given symbol */ - public SymbolTablePrinter printSymbolName(Symbol symbol) { - print(getSymbolName(symbol)); - return printSymbolUniqueId(symbol); - } - - /** Prints the kind and the name of the given symbol. */ - public SymbolTablePrinter printSymbolKindAndName(Symbol symbol) { - if (symbol.isAnonymousClass()) { - print("<template>"); - return printSymbolUniqueId(symbol); - } else { - String kind = getSymbolKind(symbol); - if (kind != null) print(kind).space(); - return printSymbolName(symbol); - } - } - - /** Prints the type of the given symbol with the given inner string. */ - public SymbolTablePrinter printSymbolType(Symbol symbol, String inner) { - Type type = symbol.rawFirstInfo(); - if (!(type instanceof Type.LazyType)) type = symbol.info(); - boolean star = false; - if ((symbol.flags & Modifiers.REPEATED) != 0 && - type.symbol() == global.definitions.SEQ_CLASS && - type.typeArgs().length == 1) - { - type = type.typeArgs()[0]; - star = true; - } - printType(type, inner); - if (star) print("*"); - return this; - } - - /** Prints the signature of the given symbol. */ - public SymbolTablePrinter printSignature(Symbol symbol) { - String keyword = getSymbolKeyword(symbol); - if (keyword != null) print(keyword).space(); - String inner = getSymbolInnerString(symbol); - return printSymbolName(symbol) - .printType(symbol.loBound(), " >: ") - .printSymbolType(symbol, inner); - } - - - /** Prints the given type parameter section. */ - public SymbolTablePrinter printTypeParams(Symbol[] tparams) { - print('['); - for (int i = 0; i < tparams.length; i++) { - if (i > 0) print(","); - printSignature(tparams[i]); - } - return print(']'); - } - - /** Prints the given value parameter section. */ - public SymbolTablePrinter printValueParams(Symbol[] vparams) { - print('('); - for (int i = 0; i < vparams.length; i++) { - if (i > 0) print(","); - printSymbolType(vparams[i], - vparams[i].isDefParameter() ? "=> " : ""); - } - return print(')'); - } - - //######################################################################## - // Public Methods - Printing types - - /** Returns the type to print for the given type (transitive). */ - public Type getTypeToPrintForType(Type type) { - while (true) { - Type result = getTypeToPrintForType0(type); - if (result == type) return result; - type = result; - } - } - - /** Returns the type to print for the given type (non-transitive). */ - public Type getTypeToPrintForType0(Type type) { - switch (type) { - case ThisType(Symbol clasz): - if (global.debug || !clasz.isModuleClass()) return type; - Type prefix = getTypeToPrintForType(clasz.owner().thisType()); - Symbol module = clasz.sourceModule(); - if (module.owner() != clasz.owner()) return type; - if (!module.type().isObjectType()) return type; - return Type.singleType(prefix, module); - case SingleType(_, Symbol sym): - if (global.debug) return type; - if (sym.isSynthetic()) return type.widen(); - return type; - case CompoundType(Type[] parts, Scope members): - if (global.debug) return type; - if (type.isFunctionType()) return parts[1]; - return type; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != Type.NoType) return constr.inst; - return type; - default: - return type; - } - } - - /** Prints the given types separated by infix. */ - public SymbolTablePrinter printTypes(Type[] types, String infix) { - for (int i = 0; i < types.length; i++) { - if (i > 0) print(infix); - printType(types[i]); - } - return this; - } - - /** Prints the given type. */ - public SymbolTablePrinter printType(Type type) { - return printType0(getTypeToPrintForType(type)); - } - public SymbolTablePrinter printType0(Type type) { - printCommonPart(type); - switch (type) { - case ThisType(_): - case SingleType(_,_): - return print(".type"); - default: - return this; - } - } - - /** Prints the given type with the given inner string. */ - public SymbolTablePrinter printType(Type type, String inner) { - if (" <: ".equals(inner) && type.symbol() == global.definitions.ANY_CLASS || - " >: ".equals(inner) && type.symbol() == global.definitions.ALL_CLASS) - return this; - else - return printType0(getTypeToPrintForType(type), inner); - } - public SymbolTablePrinter printType0(Type type, String inner) { - switch (type) { - case PolyType(Symbol[] tparams, Type result): - if (tparams.length != 0 || global.debug) printTypeParams(tparams); - return printType(result, inner); - case MethodType(Symbol[] vparams, Type result): - return printValueParams(vparams).printType(result, inner); - default: - print(inner); - return printType0(type); - } - } - - /** Prints a function type with the given type arguments. */ - public SymbolTablePrinter printFunctionType(Type[] types) { - Type[] args = new Type[types.length - 1]; - for (int i = 0; i < args.length; i++) args[i] = types[i]; - print('(').printTypes(args, ",").print(") => "); - printType(types[types.length - 1]); - return this; - } - - /** Prints a template type with the given base types. */ - public SymbolTablePrinter printTemplateType(Type[] types) { - print("<template: ").printTypes(types, " with ").print(" {...}>"); - return this; - } - - /** Prints the type and prefix common part of the given type. */ - public SymbolTablePrinter printCommonPart(Type type) { - switch (type) { - case ErrorType: - return print("<error>"); - case AnyType: - return print("<any type>"); - case NoType: - return print("<notype>"); - case NoPrefix: - return print("<noprefix>"); - case ThisType(Symbol sym): - if ((sym.isAnonymousClass() || sym.isCompoundSym()) && !global.debug) - return print("this"); - return printSymbolName(sym).print(".this"); - case TypeRef(Type pre, Symbol sym, Type[] args): - if (!global.debug) { - if (type.isFunctionType()) - return printFunctionType(args); - if (sym.isAnonymousClass() || sym.isCompoundSym()) - return printTemplateType(pre.memberInfo(sym).parents()); - } - printPrefix(pre).printSymbolName(sym); - //print("{" + sym.owner() + "}");//DEBUG - if (args.length != 0) print('[').printTypes(args, ",").print(']'); - return this; - case SingleType(Type pre, Symbol sym): - return printPrefix(pre).printSymbolName(sym); - case ConstantType(Type base, AConstant value): - return printType(base).printConstantValue(value); - case CompoundType(Type[] parts, Scope members): - return printTypes(parts," with ").space() - .printScope(members,true) - .printSymbolUniqueId(type.symbol()); - case MethodType(_, _): - return printType0(type, "" /*null*/); - case PolyType(_, _): - return printType0(type, "" /*null*/); - case OverloadedType(Symbol[] alts, Type[] alttypes): - return printTypes(alttypes, " <and> "); - case TypeVar(Type origin, Constraint constr): - return printType(origin).print("?"); - case UnboxedType(int kind): - return print(type.unboxedName(kind).toString()); - case UnboxedArrayType(Type elemtp): - return printType(elemtp).print("[]"); - case LazyType(): - if (!global.debug) return print("?"); - String classname = type.getClass().getName(); - return print("<lazy type ").print(classname).print(">"); - default: - String classname = type.getClass().getName(); - return print("<unknown type ").print(classname).print(">"); - } - } - - //######################################################################## - // Public Methods - Printing prefixes - - /** Returns the type to print for the given prefix (transitive). */ - public Type getTypeToPrintForPrefix(Type prefix) { - while (true) { - Type result = getTypeToPrintForPrefix0(prefix); - if (result == prefix || result == null) return result; - prefix = result; - } - } - - /** Returns the type to print for the given prefix (non-transitive). */ - public Type getTypeToPrintForPrefix0(Type prefix) { - if (!global.debug) { - if (prefix.symbol().isNone()) return null; - if (prefix.symbol().isRoot()) return null; - } - return getTypeToPrintForType0(prefix); - } - - /** Prints the given type as a prefix. */ - public SymbolTablePrinter printPrefix(Type prefix) { - prefix = getTypeToPrintForPrefix(prefix); - return prefix == null ? this : printPrefix0(prefix); - } - public SymbolTablePrinter printPrefix0(Type prefix) { - printCommonPart(prefix); - switch (prefix) { - case NoPrefix: - case ThisType(_): - case SingleType(_,_): - return print("."); - default: - return print("#"); - } - } - - //######################################################################## - // Public Methods - Printing constants - - /** Prints the given constant value. */ - public SymbolTablePrinter printConstantValue(AConstant value) { - return print("(").print(value.toString()).print(")"); - } - - //######################################################################## - // Public Methods - Converting - - /** Returns the string representation of this printer. */ - public String toString() { - return printer.toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java deleted file mode 100644 index 0461525710..0000000000 --- a/sources/scalac/symtab/Type.java +++ /dev/null @@ -1,3736 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** -** $Id$ -\* */ -//todo: T {} == T - -package scalac.symtab; - -import java.util.HashMap; - -import scala.tools.util.Position; -import scalac.ApplicationError; -import scalac.atree.AConstant; -import scalac.util.*; -import scalac.Global; - -public class Type implements Modifiers, Kinds, TypeTags, EntryTags { - - public static boolean explainSwitch = false; - private static int indent = 0; - - public case ErrorType; // not used after analysis - public case AnyType; // not used after analysis - public case NoType; - public case NoPrefix; - - /** C.this.type - */ - public case ThisType(Symbol sym) { - assert sym.isClassType(): Debug.show(sym); - } - - /** pre.sym.type - * sym represents a valueS - */ - public case SingleType(Type pre, Symbol sym) { - assert this instanceof ExtSingleType; - } - - /** Type for a numeric or string constant. - */ - public case ConstantType(Type base, AConstant value); - - /** pre.sym[args] - * sym represents a type - * for example: scala.List[java.lang.String] is coded as - * - * TypeRef( - * SingleType(ThisType(definitions.ROOT_CLASS), definitions.SCALA), - * <List>, - * new Type[]{ - * TypeRef( - * SingleType( - * SingleType(ThisType(definitions.ROOT_CLASS), definitions.JAVA), - * definitions.LANG), - * definitions.STRING, - * new Type[]{})}). - * - */ - public case TypeRef(Type pre, Symbol sym, Type[] args) { - assert this instanceof ExtTypeRef: this; - } - - /** parts_1 with ... with parts_n { members } - */ - public case CompoundType(Type[] parts, Scope members) { - assert this instanceof ExtCompoundType; - } - - /** synthetic type of a method def ...(vparams): result = ... - */ - public case MethodType(Symbol[] vparams, Type result) { - for (int i = 0; i < vparams.length; i++) - assert vparams[i].isParameter() && vparams[i].isTerm(): this; - } - - /** synthetic type of a method def ...[tparams]result - * For instance, given def f[a](x: a): a - * f has type PolyType(new Symbol[]{<a>}, - * MethodType(new Symbol[]{<x>}, <a>.type())) - * - * if tparams is empty, this is the type of a parameterless method - * def ... = - * For instance, given def f = 1 - * f has type PolyType(new Symbol[]{}, <scala.Int>.type()) - */ - public case PolyType(Symbol[] tparams, Type result) { - for (int i = 0; i < tparams.length; i++) - assert tparams[i].isParameter()&&tparams[i].isAbstractType(): this; - } - - /** synthetic type of an overloaded value whose alternatives are - * alts_1, ..., alts_n, with respective types alttypes_1, ..., alttypes_n - * - * For instance, if there are two definitions of `f' - * def f: int - * def f: String - * then there are three symbols: - * ``f1'' corresponding to def f: int - * ``f2'' corresponding to def f: String - * ``f3'' corresponding to both - * f3 has type - * OverloadedType( - * new Symbol[]{<f1>, <f2>}, - * new Type[]{PolyType(new Symbol[]{}, <int>), - * PolyType(new Symbol[]{}, <String>), - * - */ - public case OverloadedType(Symbol[] alts, Type[] alttypes); - - /** Hidden case to implement delayed evaluation of types. - * No need to pattern match on this type; it will never come up. - */ - public case LazyType(); - - /** Hidden case to implement local type inference. - * Later phases do not need to match on this type. - */ - public case TypeVar(Type origin, Constraint constr); - - /** Hidden cases to implement type erasure. - * Earlier phases do not need to match on these types. - */ - public case UnboxedType(int tag); - public case UnboxedArrayType(Type elemtp); - - /** Force evaluation of a lazy type. No cycle - * check is needed; since this is done in Symbol. - * @see Symbol.info(). - */ - public void complete(Symbol p) {} - -// Creators --------------------------------------------------------------------- - - /** An empty Type array */ - public static final Type[] EMPTY_ARRAY = new Type[0]; - - public static SingleType singleType(Type pre, Symbol sym) { - assert sym.isTerm() && !sym.isNone(): pre + " -- " + Debug.show(sym); - rebind: - { - Symbol owner = sym.owner(); - if (!owner.isClass()) break rebind; - if (owner == pre.symbol()) break rebind; - // !!! add if (owner is sealed/final) break rebind ? - // !!! add if (owner is module class) break rebind ? - if (sym.isFinal() || sym.isPrivate()) break rebind; - Symbol rebind = pre.lookupNonPrivate(sym.name); - if (rebind.isNone()) break rebind; - if (rebind.isLocked()) throw new Type.Error( - "illegal cyclic reference involving " + rebind); - sym = rebind.rebindSym().stableAlternative(); - } - if (pre.isStable() || pre.isError()) { - return new ExtSingleType(pre, sym); - } else { - throw new Type.Malformed(pre, sym.nameString() + ".type"); - } - } - - public static Type constantType(AConstant value) { - return Global.instance.definitions.atyper.type(value); - } - - public static Type singleTypeMethod(Type pre, Symbol sym) { - Global global = Global.instance; - if (global.currentPhase.id <= global.PHASE.UNCURRY.id()) - return singleType(pre, sym); - else if (global.currentPhase.id <= global.PHASE.ERASURE.id()) - return sym.type().singleTypeMethod0(pre, sym); - else - return pre.memberType(sym); - } - - private Type singleTypeMethod0(Type pre, Symbol sym) { - switch (this) { - case PolyType(Symbol[] args, Type result): - return PolyType(args, result.singleTypeMethod0(pre, sym)); - case MethodType(Symbol[] args, Type result): - return MethodType(args, result.singleTypeMethod0(pre, sym)); - default: - return singleType(pre, sym); - } - } - - public static Type appliedType(Type tycon, Type[] args) { - switch (tycon) { - case TypeRef(Type pre, Symbol sym, Type[] args1): - if (args == args1) return tycon; - else return Type.typeRef(pre, sym, args); - default: - throw Debug.abort("illegal case", tycon); - } - } - - public static Type typeRef(Type pre, Symbol sym, Type[] args) { - rebind: - if (sym.isAbstractType()) { - Symbol owner = sym.owner(); - if (!owner.isClass()) break rebind; - if (owner == pre.symbol()) break rebind; - // !!! add if (owner is sealed/final) break rebind ? - // !!! add if (owner is module class) break rebind ? - if (sym.isFinal() || sym.isPrivate()) break rebind; - Symbol rebind = pre.lookupNonPrivate(sym.name); - if (rebind.isNone()) break rebind; - if (rebind.isLocked()) throw new Type.Error( - "illegal cyclic reference involving " + rebind); - sym = rebind.rebindSym(); - } - if (sym.isAbstractType() && !pre.isLegalPrefix() && !pre.isError()) - throw new Type.Malformed(pre, sym.nameString()); - if (sym.isTypeAlias()) { - Symbol[] params = sym.typeParams(); - if (args.length == params.length) { - if (sym.isLocked()) throw new Type.Error( - "illegal cyclic reference involving " + sym); - sym.flags |= LOCKED; - Type result = pre.memberInfo(sym).subst(params, args); - sym.flags &= ~LOCKED; - return result; - } - assert args.length == 0 || args.length == params.length: - Debug.show(pre, sym, args, params); - } - assert isLegalTypeRef(pre, sym, args): - Debug.show(pre, sym, args, sym.typeParams()); - return new ExtTypeRef(pre, sym, args); - } - private static boolean isLegalTypeRef(Type pre, Symbol sym, Type[] args) { - if (sym.kind == TYPE && !pre.isLegalPrefix() && !pre.isError()) return false; - if (!sym.isType() && !sym.isError()) return false; - // !!! return args.length == 0 || args.length == sym.typeParams().length; - return true; - } - - public static Type newTypeRefUnsafe(Type pre, Symbol sym, Type[] args) { - return new ExtTypeRef(pre, sym, args); - } - - public static CompoundType compoundType(Type[] parts, Scope members, - Symbol clazz) { - return new ExtCompoundType(parts, members, clazz); - } - - public static CompoundType compoundTypeWithOwner(Symbol owner, Type[] parts, Scope members) { - return new ExtCompoundType(owner, parts, members); - } - - static class ExtSingleType extends SingleType { - Type tp = null; - int definedId = -1; - ExtSingleType(Type pre, Symbol sym) { - super(pre, sym); - } - public Type singleDeref() { - if (definedId != Global.instance.currentPhase.id) { - definedId = Global.instance.currentPhase.id; - tp = pre.memberType(sym).resultType(); - } - return tp; - } - } - - static class ExtTypeRef extends TypeRef { - ExtTypeRef(Type pre, Symbol sym, Type[] args) { - super(pre, sym, args); - } - } - - private static final class ExtCompoundType extends CompoundType { - private final Symbol clasz; - public ExtCompoundType(Symbol owner, Type[] parts, Scope members) { - super(parts, members); - this.clasz = owner.newCompoundClass(this); - } - public ExtCompoundType(Type[] parts, Scope members, Symbol clasz) { - super(parts, members); - this.clasz = clasz; - } - public Symbol symbol() { - return clasz; - } - } - -// Access methods --------------------------------------------------------------- - - /** If this is a thistype, named type, applied type, singleton type, or compound type, - * its symbol, otherwise Symbol.NONE. - */ - public Symbol symbol() { - switch (this) { - case ThisType(Symbol sym): - return sym; - case TypeRef(_, Symbol sym, _): - return sym; - case SingleType(_, Symbol sym): - return sym; - case ConstantType(Type base, _): - return base.symbol(); - case TypeVar(Type origin, _): - return origin.symbol(); - case CompoundType(_, _): - // overridden in ExtCompoundType - throw new ApplicationError(); - default: - return Symbol.NONE; - } - } - - public static Symbol[] symbol(Type[] tps) { - Symbol[] syms = new Symbol[tps.length]; - for (int i = 0; i < syms.length; i++) - syms[i] = tps[i].symbol(); - return syms; - } - - /** If this is a reference to a type constructor, add its - * type parameters as arguments - */ - public Type withDefaultArgs() { - switch (this) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (args.length == 0 && sym.typeParams().length != 0) - return Type.typeRef(pre, sym, Symbol.type(sym.typeParams())); - } - return this; - } - - /** The upper bound of this type. Returns always a TypeRef whose - * symbol is a class. - */ - public Type bound() { - switch (unalias()) { - case TypeRef(Type pre, Symbol sym, _): - if (sym.kind == TYPE) return pre.memberInfo(sym).bound(); - assert sym.isClass() : Debug.show(sym) + " -- " + this; - return this; - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().bound(); - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.bound(); - else return this; - default: - throw Debug.abort("illegal case", this); - } - } - - /** If this type is a thistype or singleton type, its type, - * otherwise the type itself. - */ - public Type singleDeref() { - switch (this) { - case ThisType(Symbol sym): - return sym.typeOfThis(); - case SingleType(Type pre, Symbol sym): - // overridden in ExtSingleType - throw new ApplicationError(); - case ConstantType(Type base, _): - return base; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.singleDeref(); - else return this; - default: - return this; - } - } - - /** If this type is a thistype or singleton type, its underlying object type, - * otherwise the type itself. - */ - public Type widen() { - Type tp = singleDeref(); - switch (tp) { - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return tp.widen(); - default: - return tp; - } - } - - private static Map widenMap = new Map() { - public Type apply(Type t) { - return t.widen(); - } - }; - - public static Type[] widen(Type[] tps) { - return widenMap.map(tps); - } - - /** The thistype or singleton type corresponding to values of this type. - */ - public Type narrow() { - switch (unalias()) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == CLASS) return sym.thisType(); - else return ThisType(sym); - case CompoundType(_, _): - return symbol().thisType(); - default: - return this; - } - } - - /** If this type is a constant type, its underlying basetype; - * otherwise the type itself - */ - public Type deconst() { - switch (this) { - case ConstantType(Type base, _): - return base; - default: - return this; - } - } - - /** If this type is a parameterless method, its underlying resulttype; - * otherwise the type itself - */ - public Type derefDef() { - switch (this) { - case PolyType(Symbol[] tparams, Type restp): - if (tparams.length == 0) return restp; - } - return this; - } - - /** The lower approximation of this type (which must be a typeref) - */ - public Type loBound() { - switch (unalias()) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Type lb = Global.instance.definitions.ALL_TYPE(); - if (sym.kind == TYPE) { - lb = pre.memberLoBound(sym); - } - if (lb.symbol() == Global.instance.definitions.ALL_CLASS && - this.symbol() != Global.instance.definitions.ALL_CLASS && - this.isSubType(Global.instance.definitions.ANYREF_TYPE())) { - lb = Global.instance.definitions.ALLREF_TYPE(); - } - return lb; - default: - throw new ApplicationError(); - } - } - - /** If this is a this-type, named-type, applied type or single-type, its prefix, - * otherwise NoType. - */ - public Type prefix() { - switch (this) { - case ThisType(Symbol sym): return sym.owner().thisType(); - case TypeRef(Type pre, _, _): return pre; - case SingleType(Type pre, _): return pre; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.prefix(); - else return NoType; - default: return NoType; - } - } - - /** Get all type arguments of this type. - */ - public Type[] typeArgs() { - switch (unalias()) { - case TypeRef(_, _, Type[] args): - return args; - default: - return Type.EMPTY_ARRAY; - } - } - - /** Get type of `this' symbol corresponding to this type, extend - * homomorphically to function types and poly types. - */ - public Type instanceType() { - switch (unalias()) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym != sym.thisSym()) - return sym.typeOfThis() - .asSeenFrom(pre, sym.owner()) - .subst(sym.typeParams(), args); - break; - case MethodType(Symbol[] params, Type restp): - Type restp1 = restp.instanceType(); - if (restp1 != restp) - return MethodType(params, restp1); - break; - case PolyType(Symbol[] tparams, Type restp): - Type restp1 = restp.instanceType(); - if (restp1 != restp) - return PolyType(tparams, restp1); - break; - } - return this; - } - - /** Remove all aliases - */ - public Type unalias() { - Type result = unalias(0);//debug - //if (this != result) System.out.println(this + " ==> " + result);//DEBUG - return result; - } - - private Type unalias(int n) { - if (n == 100) - throw new Type.Error("alias chain too long (recursive type alias?): " + this); - switch (this) { - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.unalias(n + 1); - else return this; - } - return this; - } - - /** The (prefix/argument-adapted) parents of this type. - */ - public Type[] parents() { - switch (unalias()) { - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().parents(); - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == CLASS) { - assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args) + " " + sym.primaryConstructor().info();//debug - return subst(asSeenFrom(sym.info().parents(), pre, sym.owner()), - sym.typeParams(), args); - } else { - return new Type[]{sym.info().asSeenFrom(pre, sym.owner())}; - } - case CompoundType(Type[] parts, _): - return parts; - default: - return Type.EMPTY_ARRAY; - } - } - - /** Get type parameters of method type (a PolyType or MethodType) - * or EMPTY_ARRAY if method type is not polymorphic. - */ - public Symbol[] typeParams() { - switch (this) { - case PolyType(Symbol[] tparams, _): - return tparams; - case MethodType(Symbol[] vparams, _): - return Symbol.EMPTY_ARRAY; - case TypeRef(_, Symbol sym, Type[] args): - if (args.length == 0) return sym.typeParams(); - else return Symbol.EMPTY_ARRAY; - default: - return Symbol.EMPTY_ARRAY; - } - } - - /** Get value parameters of method type (a PolyType or MethodType) - * or EMPTY_ARRAY if method type has no value parameter section. - */ - public Symbol[] valueParams() { - return valueParams(false); - } - private Symbol[] valueParams(boolean ok) { - switch (this) { - case PolyType(_, Type result): - return result.valueParams(true); - case MethodType(Symbol[] vparams, _): - return vparams; - default: - if (ok) return Symbol.EMPTY_ARRAY; - throw Debug.abort("illegal case", this); - } - } - - /** If this type is a (possibly polymorphic) method type, its result type - * after applying all method argument sections, - * otherwise the type itself. - */ - public Type resultType() { - switch (this) { - case PolyType(_, Type tpe): - return tpe.resultType(); - case MethodType(_, Type tpe): - return tpe.resultType(); - default: - return this; - } - } - - /** The number of value parameter sections of this type. - */ - public int paramSectionCount() { - switch (this) { - case PolyType(_, Type restpe): - return restpe.paramSectionCount(); - case MethodType(_, Type restpe): - return restpe.paramSectionCount() + 1; - default: return 0; - } - } - - /** The first parameter section of this type. - */ - public Symbol[] firstParams() { - switch (this) { - case PolyType(_, Type restpe): - return restpe.firstParams(); - case MethodType(Symbol[] params, _): - return params; - default: return Symbol.EMPTY_ARRAY; - } - } - - /** If this type is overloaded, its alternative types, - * otherwise an array consisting of this type itself. - */ - public Type[] alternativeTypes() { - switch (this) { - case OverloadedType(_, Type[] alttypes): - return alttypes; - default: - return new Type[]{this}; - } - } - - /** If this type is overloaded, its alternative symbols, - * otherwise an empty array. - */ - public Symbol[] alternativeSymbols() { - switch (this) { - case OverloadedType(Symbol[] alts, _): - return alts; - default: - return Symbol.EMPTY_ARRAY; - } - } - -// Tests -------------------------------------------------------------------- - - /** Is this type a an error type? - */ - public boolean isError() { - switch (this) { - case ErrorType: - return true; - case ThisType(Symbol clasz): - return clasz.isError(); - case SingleType(_, Symbol symbol): - return symbol.isError(); - case TypeRef(_, Symbol symbol, _): - return symbol.isError(); - case CompoundType(Type[] parts, Scope members): - return symbol().isError(); - default: - return false; - } - } - - /** Is this type a this type or singleton type? - */ - public boolean isStable() { - switch (unalias()) { - case NoPrefix: - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return true; - case TypeRef(_, Symbol sym, _): - if (sym.isParameter() && sym.isSynthetic() && sym.hasStableFlag()) return true; - return false; - default: - return false; - } - } - - /** Is this type a legal prefix? - */ - public boolean isLegalPrefix() { - switch (unalias()) { - case NoPrefix: - case ThisType(_): - case SingleType(_, _): - return true; - case TypeRef(_, Symbol sym, _): - if (sym.isParameter() && sym.isSynthetic()) return true; - return false; - /* - return sym.kind == CLASS && - ((sym.flags & JAVA) != 0 || - (sym.flags & (TRAIT | ABSTRACT)) == 0); - */ - default: - return false; - } - } - - /** Is this type a s thistype or singletype? - */ - public boolean isSingletonType() { - switch (this) { - case ThisType(_): case SingleType(_, _): return true; - default: return false; - } - } - - /** Is this type a reference to an object type? - * todo: replace by this.isSubType(global.definitions.ANY_TYPE())? - */ - public boolean isObjectType() { - switch (unalias()) { - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - case CompoundType(_, _): - case TypeRef(_, _, _): - return true; - default: - return false; - } - } - - /** Is this type of the form scala.FunctionN[T_1, ..., T_n, +T] or - * scala.AnyRef with scala.FunctionN[T_1, ..., T_n, +T] or - * java.lang.Object with scala.FunctionN[T_1, ..., T_n, +T]? - */ - public boolean isFunctionType() { - switch (this) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Definitions definitions = Global.instance.definitions; - return args.length > 0 - && args.length <= definitions.FUNCTION_COUNT - && sym == definitions.FUNCTION_CLASS[args.length - 1]; - case CompoundType(Type[] parents, Scope members): - Definitions definitions = Global.instance.definitions; - return members.isEmpty() && - parents.length == 2 && - (parents[0].symbol() == definitions.OBJECT_CLASS || - parents[0].symbol() == definitions.ANYREF_CLASS) && - parents[1].isFunctionType(); - } - return false; - } - - /** Is this a polymorphic method type? - */ - public boolean isPolymorphic() { - return typeParams().length > 0; - } - - /** Is this a parameterized or polymorphic method type? - */ - public boolean isParameterized() { - switch (this) { - case MethodType(_, _): return true; - default: return isPolymorphic(); - } - } - -// Members and Lookup ------------------------------------------------------- - - /** Get the scope containing the local members of this type. - * Symbols in this scope are not prefix-adapted! - */ - public Scope members() { - switch (this) { - case ErrorType: - return new Scope(); - case TypeRef(_, Symbol sym, _): - return sym.info().members(); - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().members(); - case CompoundType(Type[] basetypes, Scope members): - return members; - default: - return Scope.EMPTY; - } - } - - /** Lookup symbol with given name among all local and inherited members - * of this type; return Symbol.NONE if not found. - */ - public Symbol lookup(Name name) { - // The code below does the same as the following line but is - // slightly faster - // return lookup(new NameSearch(name, false)); - - switch (this) { - case ErrorType: - return new ErrorScope(Symbol.NONE).lookup(name); - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().lookup(name); - case TypeRef(_, Symbol sym, _): - return sym.info().lookup(name); - case CompoundType(Type[] parts, Scope members): - Symbol sym = members.lookup(name); - if (sym.kind != NONE) return sym; - else return lookupNonPrivate(name); - default: - return Symbol.NONE; - } - } - - /** Lookup non-private symbol with given name among all local and - * inherited members of this type; return Symbol.NONE if not found. - */ - public Symbol lookupNonPrivate(Name name) { - // The code below does the same as the following line but is - // slightly faster - // return lookup(new NameSearch(name, true)); - - switch (this) { - case ErrorType: - return new ErrorScope(Symbol.NONE).lookup(name); - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().lookupNonPrivate(name); - case TypeRef(_, Symbol sym, _): - return sym.info().lookupNonPrivate(name); - case CompoundType(Type[] parts, Scope members): - Symbol sym = members.lookup(name); - if (sym.kind != NONE && (sym.flags & PRIVATE) == 0) return sym; - else return lookupNonPrivate(parts, name); - default: - return Symbol.NONE; - } - } - - public static Symbol lookupNonPrivate(Type[] parts, Name name) { - // The code below does the same as the following line but is - // slightly faster - // return lookup(parts, new NameSearch(name, true)); - - // search base types in reverse; non-abstract members - // take precedence over abstract ones. - int i = parts.length; - Symbol sym = Symbol.NONE; - while (i > 0) { - i--; - Symbol sym1 = parts[i].lookupNonPrivate(name); - if (sym1.kind != NONE && - (sym.kind == NONE - || - (sym.flags & DEFERRED) != 0 && - (sym1.flags & DEFERRED) == 0 - || - (sym.flags & DEFERRED) == (sym1.flags & DEFERRED) && - sym1.owner().isSubClass(sym.owner()))) - sym = sym1; - } - return sym; - } - - /** - * Looks up in the current type a symbol with the same name as the - * given symbol and whose type (as seen from the given prefix) is - * in the given relation to the type (as seen from the given - * prefix) of the given symbol. If no such symbol is found, - * returns NONE. Note that in some cases, the returned symbol may - * be equal to the given one. The main purpose of this method is - * look up overridden and overriding symbols. - */ - public Symbol lookup(Symbol symbol, Type prefix, Relation relation) { - assert !symbol.isOverloaded(): Debug.show(symbol); - if (symbol.isPrivate() || symbol.isInitializer()) - return symbol().isSubClass(symbol.owner()) ? symbol : Symbol.NONE; - Symbol best = search(new SymbolSearch(symbol, prefix, relation)); - return best == null ? Symbol.NONE : best; - } - - /** - * Applies the given search to this type. Returns NONE on failure. - */ - public Symbol lookup(Search search) { - Symbol symbol = search(search); - return symbol == null ? Symbol.NONE : symbol; - } - - /** - * Applies the given search to the given types. Returns NONE on - * failure. - */ - public static Symbol lookup(Type[] parents, Search search) { - Symbol symbol = search(parents, search); - return symbol == null ? Symbol.NONE : symbol; - } - - /** - * Applies the given search to this type. Returns null on failure. - */ - public Symbol search(Search search) { - return search(this, search, null, false); - } - - /** - * Applies the given search to the given types. Returns null on - * failure. - */ - public static Symbol search(Type[] parents, Search search) { - Symbol best = null; - for (int i = parents.length - 1; 0 <= i; i--) - best = search(parents[i], search, best, true); - return best; - } - - /** - * Applies the given search to the given type. The symbol "best" - * is the best symbol found until now. It may be null. If no - * better symbol is found, the method returns this symbol. The - * flag "inherited" indicates whether the given type is the - * initial type (false) or is a type inherited by it (true). - */ - private static Symbol search(Type type, Search search, Symbol best, - boolean inherited) - { - while (true) { - switch (type) { - case ErrorType: - return best != null ? best : search.error(); - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - type = type.singleDeref(); - continue; - case TypeRef(_, Symbol symbol, _): - type = symbol.info(); - continue; - case CompoundType(Type[] parents, Scope members): - // The following code could be used to cut the search, but - // it is unclear whether it is faster - // if (best != null && !best.isDeferred()) - // if (!type.symbol().isSubClass(best.owner())) return best; - Symbol symbol = search.apply(members, inherited); - if (symbol != null) { - // !!! This assertion fails for "pos/clsrefine". - // There might be a bug in the analyzer. - // assert type.symbol().isSubClass(symbol.owner()): - // Debug.show(type, type.symbol(), symbol); - if ((best == null) - || - (best.isDeferred() && !symbol.isDeferred()) - || - ((best.isDeferred() == symbol.isDeferred()) && - symbol.owner().isSubClass(best.owner()))) - return symbol; - } - for (int i = parents.length - 1; 0 <= i; i--) - best = search(parents[i], search, best, true); - return best; - default: - return null; - } - } - } - - public static abstract class Search { - /** - * This method is applied to each encountered scope. The flag - * "inherited" indicates whether the scope is part of the - * initial type (false) or if it is inherited by it (true). - */ - public abstract Symbol apply(Scope members, boolean inherited); - /** This method is applied to each encountered error type. */ - public abstract Symbol error(); - } - - /** Seaches a symbol with the given name. */ - public static class NameSearch extends Search { - public final Name name; - public final boolean nonPrivate; - public NameSearch(Name name, boolean nonPrivate) { - this.name = name; - this.nonPrivate = nonPrivate; - } - public Symbol apply(Scope members, boolean inherited) { - Symbol symbol = members.lookup(name); - if (!symbol.isNone()) - if (!inherited || !nonPrivate || (symbol.flags & PRIVATE) == 0) - return symbol; - return null; - } - public Symbol error() { - return name.isTermName() - ? Symbol.NONE.newErrorValue(name) - : Symbol.NONE.newErrorClass(name); - } - } - - /** - * Searches a symbol with the same name as the given source symbol - * and whose type (as seen from the given prefix) is in the given - * relation to the type (as seen from the given prefix) of the - * source symbol. Note that in some cases, the returned symbol may - * be equal to the source one. This search is useful to find - * overridden and overriding symbols. - */ - public static class SymbolSearch extends Search { - - /** The type which the symbols are seen from */ - public final Type prefix; - /** The source symbol */ - public final Symbol srcsym; - /** The source symbol's type as seen from the prefix */ - public final Type srctype; - /** The java version of the previous type */ - public Type srcjavatype; - /** The type relation between returned and source symbols. */ - public final Relation relation; - - public SymbolSearch(Symbol srcsym, Type prefix, Relation relation) { - this.prefix = prefix; - this.srcsym = srcsym; - this.srctype = getSeenTypeOf(srcsym); - this.relation = relation; - assert !srcsym.isOverloaded(): Debug.show(srcsym); - } - - public Symbol apply(Scope members, boolean inherited) { - Symbol objsym = members.lookup(srcsym.name); - if (objsym.isNone()) return null; - switch (objsym.type()) { - case NoType: - case ErrorType: - return null; - case OverloadedType(Symbol[] alts, _): - for (int j = 0; j < alts.length; j++) - if (areRelated(alts[j], false)) return alts[j]; - return null; - default: - return areRelated(objsym, true) ? objsym : null; - } - } - - public Symbol error() { - return null; - } - - private Type getSeenTypeOf(Symbol symbol) { - return prefix.memberType(symbol).derefDef(); - } - - private Type getSrcTypeFor(Symbol objsym) { - if (!objsym.isJava()) return srctype; - if (srcjavatype == null) srcjavatype = srctype.objParamToAny(); - return srcjavatype; - } - - private boolean areRelated(Symbol objsym, boolean warn) { - if (objsym == srcsym) return true; - if (objsym.isPrivate() || objsym.isInitializer()) return false; - Type srctype = getSrcTypeFor(objsym); - Type objtype = getSeenTypeOf(objsym); -// System.out.println("" -// + "Is 'objsym' " + relation + " 'srcsym' in 'prefix' ?" -// + "\n srcsym : " + Debug.show(srcsym) -// + "\n objsym : " + Debug.show(objsym) -// + "\n srcsym.type: " + srcsym.type() -// + "\n objsym.type: " + objsym.type() -// + "\n prefix : " + prefix -// + "\n srctype : " + srctype -// + "\n objtype : " + objtype -// + "\n result : " + objtype.compareTo(srctype, relation) -// );//DEBUG - if (objtype.compareTo(srctype, relation)) return true; - if (warn && Global.instance.debug) System.out.println("" - + "'objsym' is not " + relation + " 'srcsym' in 'prefix'" - + "\n srcsym : " + Debug.show(srcsym) - + "\n objsym : " + Debug.show(objsym) - + "\n srcsym.type: " + srcsym.type() - + "\n objsym.type: " + objsym.type() - + "\n prefix : " + prefix - + "\nsince 'objtype' " + relation.toString(true) + " 'srctype'" - + "\n srctype : " + srctype - + "\n objtype : " + objtype - );//DEBUG - return false; - } - - } - //where - static private Map objToAnyMap = new Map() { - public Type apply(Type t) { - if (t.symbol() == Global.instance.definitions.OBJECT_CLASS) - return Global.instance.definitions.ANY_TYPE(); - else return t; - } - }; - - private Type objParamToAny() { - switch (this) { - case MethodType(Symbol[] params, Type restp): - Symbol[] params1 = objToAnyMap.map(params); - if (params1 == params) return this; - else return MethodType(params1, restp); - default: - return this; - } - } - -// Set Owner ------------------------------------------------------------------ - - public Type setOwner(Symbol owner) { - switch (this) { - case PolyType(Symbol[] tparams, Type restpe): - Type restpe1 = restpe.setOwner(owner); - if (restpe1 == restpe) return this; - else return Type.PolyType(tparams, restpe1); - case MethodType(Symbol[] params, Type restpe): - Symbol[] params1 = params; - if (params.length > 0 && - params[0].owner() != owner && params[0].owner() != Symbol.NONE) { - params1 = new Symbol[params.length]; - for (int i = 0; i < params.length; i++) - params1[i] = params[i].cloneSymbol(); - } - for (int i = 0; i < params.length; i++) - params1[i].setOwner(owner); - Type restpe1 = restpe.setOwner(owner); - if (params1 == params && restpe1 == restpe) return this; - else return Type.MethodType(params1, restpe1); - default: - return this; - } - } - -// Maps -------------------------------------------------------------------------- - - /** The type of type-to-type functions. - */ - public abstract static class Map { - - public abstract Type apply(Type t); - - /** - * This method assumes that all symbols in MethodTypes and - * PolyTypes have already been cloned. - */ - public Type applyParams(Type type) { - switch (type) { - - case MethodType(Symbol[] vparams, Type result): - map(vparams, true); - Type result1 = applyParams(result); - return result == result1 ? type : MethodType(vparams, result1); - - case PolyType(Symbol[] tparams, Type result): - map(tparams, true); - Type result1 = applyParams(result); - return result == result1 ? type : PolyType(tparams, result1); - - default: - return apply(type); - } - } - - /** Apply map to all top-level components of this type. - */ - public Type map(Type tp) { - switch (tp) { - case ErrorType: - case AnyType: - case NoType: - case NoPrefix: - case UnboxedType(_): - case TypeVar(_, _): - case ThisType(_): - return tp; - case TypeRef(Type pre, Symbol sym, Type[] args): - Type pre1 = apply(pre); - Type[] args1 = map(args); - if (pre1 == pre && args1 == args) return tp; - else return typeRef(pre1, sym, args1); - case SingleType(Type pre, Symbol sym): - Type pre1 = apply(pre); - if (pre1 == pre) return tp; - else return singleType(pre1, sym); - case ConstantType(Type base, AConstant value): - Type base1 = apply(base); - if (base1 == base) return tp; - else return new ConstantType(base1, value); - case CompoundType(Type[] parts, Scope members): - Type[] parts1 = map(parts); - Scope members1 = map(members); - if (parts1 == parts && members1 == members) { - return tp; - } else if (members1 == members && !tp.symbol().isCompoundSym()) { - return compoundType(parts1, members, tp.symbol()); - } else { - Scope members2 = new Scope(); - //Type tp1 = compoundType(parts1, members2); - Type tp1 = (tp.symbol().isCompoundSym()) ? compoundTypeWithOwner(tp.symbol().owner(), parts1, members2) - : compoundType(parts1, members2, tp.symbol()); - Symbol[] syms1 = members1.elements(); - Symbol[] syms2 = new Symbol[syms1.length]; - for (int i = 0; i < syms2.length; i++) { - syms2[i] = syms1[i].cloneSymbol(tp1.symbol()); - } - for (int i = 0; i < syms2.length; i++) { - syms2[i].setInfo(syms1[i].info().subst(syms1, syms2)); - if (syms2[i].kind == TYPE) { - syms2[i].setLoBound(syms1[i].loBound().subst(syms1, syms2)); - syms2[i].setVuBound(syms1[i].vuBound().subst(syms1, syms2)); - } - } - for (int i = 0; i < syms2.length; i++) { - members2.enter(syms2[i]); - } - return tp1; - } - - case MethodType(Symbol[] vparams, Type result): - Symbol[] vparams1 = map(vparams); - Type result1 = apply(result); - if (vparams1 == vparams && result1 == result) return tp; - else return MethodType(vparams1, result1); - case PolyType(Symbol[] tparams, Type result): - Symbol[] tparams1 = map(tparams); - Type result1 = apply(result); - if (tparams1 != tparams) result1 = result1.subst(tparams, tparams1); - if (tparams1 == tparams && result1 == result) return tp; - else return PolyType(tparams1, result1); - case OverloadedType(Symbol[] alts, Type[] alttypes): - Type[] alttypes1 = map(alttypes); - if (alttypes1 == alttypes) return tp; - else return OverloadedType(alts, alttypes1); - case UnboxedArrayType(Type elemtp): - Type elemtp1 = apply(elemtp); - if (elemtp1 == elemtp) return tp; - else return UnboxedArrayType(elemtp1); - default: - throw new ApplicationError(tp + " " + tp.symbol()); - } - } - - public final Symbol map(Symbol sym) { - return map(sym, false); - } - public Symbol map(Symbol sym, boolean dontClone) { - Type tp = sym.info(); - Type tp1 = apply(tp); - if (tp != tp1) { - if (!dontClone) sym = sym.cloneSymbol(); - sym.setInfo(tp1); - dontClone = true; - } - if (sym.kind == TYPE) { - Type lb = sym.loBound(); - Type lb1 = apply(lb); - if (lb != lb1) { - if (!dontClone) sym = sym.cloneSymbol(); - sym.setLoBound(lb1); - } - Type vb = sym.vuBound(); - Type vb1 = apply(vb); - if (vb != vb1) { - if (!dontClone) sym = sym.cloneSymbol(); - sym.setVuBound(vb1); - } - } - return sym; - } - - public Type[] map(Type[] tps) { - Type[] tps1 = tps; - for (int i = 0; i < tps.length; i++) { - Type tp = tps[i]; - Type tp1 = apply(tp); - if (tp1 != tp && tps1 == tps) { - tps1 = new Type[tps.length]; - System.arraycopy(tps, 0, tps1, 0, i); - } - tps1[i] = tp1; - } - return tps1; - } - - /** Apply map to all elements of this array of symbols, - * preserving recursive references to symbols in the array. - */ - public final Symbol[] map(Symbol[] syms) { - return map(syms, false); - } - public Symbol[] map(Symbol[] syms, boolean dontClone) { - Symbol[] syms1 = syms; - for (int i = 0; i < syms.length; i++) { - Symbol sym = syms[i]; - Symbol sym1 = map(sym, dontClone); - if (sym != sym1 && syms1 == syms) { - syms1 = new Symbol[syms.length]; - System.arraycopy(syms, 0, syms1, 0, i); - } - syms1[i] = sym1; - } - if (syms1 != syms) { - for (int i = 0; i < syms1.length; i++) { - if (syms1[i] == syms[i]) - syms1[i] = syms[i].cloneSymbol(); - } - new SubstSymMap(syms, syms1).map(syms1, true); - } - return syms1; - } - - /** Apply map to all elements of this array of this scope. - */ - public Scope map(Scope s) { - Symbol[] members = s.elements(); - Symbol[] members1 = map(members); - if (members == members1) return s; - else return new Scope(members1); - } - } - - public abstract static class MapOnlyTypes extends Map { - public Symbol map(Symbol sym, boolean dontClone) { return sym; } - public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; } - public Scope map(Scope s) { return s; } - } - - public static final Map IdMap = new Map() { - public Type apply(Type tp) { return tp; } - public Type applyParams(Type tp) { return tp; } - public Type map(Type tp) { return tp; } - public Symbol map(Symbol sym, boolean dontClone) { return sym; } - public Type[] map(Type[] tps) { return tps; } - public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; } - public Scope map(Scope scope) { return scope; } - }; - -// baseType and asSeenFrom -------------------------------------------------------- - - /** Return the base type of this type whose symbol is `clazz', or NoType, if - * such a type does not exist. - */ - public Type baseType(Symbol clazz) { - //System.out.println(this + ".baseType(" + clazz + ")");//DEBUG - switch (this) { - case ErrorType: - return ErrorType; - - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().baseType(clazz); - - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym == clazz) - return this; - else if (sym.kind == TYPE) - return sym.info() - .asSeenFrom(pre, sym.owner()).baseType(clazz); - else if (sym.kind == ALIAS) - return Type.NoType; - else if (clazz.isCompoundSym()) - return NoType; - else { - return sym.baseType(clazz) - .asSeenFrom(pre, sym.owner()) - .subst(sym.typeParams(), args); - } - - case CompoundType(Type[] parts, _): - for (int i = parts.length - 1; i >= 0; i--) { - Type result = parts[i].baseType(clazz); - if (result != NoType) return result; - } - break; - - case UnboxedArrayType(_): - if (clazz == Global.instance.definitions.ANY_CLASS || - clazz == Global.instance.definitions.ANYREF_CLASS) - return clazz.type(); - } - return NoType; - } - - /** A map to implement `asSeenFrom'. - */ - static class AsSeenFromMap extends Map { - - private final Type pre; - private final Symbol clazz; - - AsSeenFromMap(Type pre, Symbol clazz) { - this.pre = pre; - this.clazz = clazz; - } - - public Type apply(Type type) { - //System.out.println(type + " as seen from " + pre + "," + clazz);//DEBUG - if (pre == NoType || clazz.kind != CLASS) return type; - switch (type) { - case ThisType(Symbol sym): - return type.toPrefix(sym, pre, clazz); - case TypeRef(Type prefix, Symbol sym, Type[] args): - if (sym.owner().isPrimaryConstructor()) { - assert sym.kind == TYPE; - return type.toInstance(sym, pre, clazz); - } - return map(type); - - case SingleType(Type prefix, Symbol sym): - try { - return map(type); - } catch (Type.Malformed ex) {} - return apply(type.singleDeref()); - - default: - return map(type); - } - } - } - //where - Type toInstance(Symbol sym, Type pre, Symbol clazz) { - if (pre == NoType || clazz.kind != CLASS) - return this; - Symbol ownclass = sym.owner().constructorClass(); - if (ownclass == clazz && - pre.widen().symbol().isSubClass(ownclass)) { - switch (pre.baseType(ownclass)) { - case TypeRef(_, Symbol basesym, Type[] baseargs): - Symbol[] baseparams = basesym.typeParams(); - for (int i = 0; i < baseparams.length; i++) { - if (sym == baseparams[i]) return baseargs[i]; - } - //System.out.println(sym + " " + basesym + " " + ArrayApply.toString(baseparams));//DEBUG - break; - case ErrorType: - return ErrorType; - } - throw new ApplicationError( - this + " in " + ownclass + " cannot be instantiated from " + pre.widen() - ); - } else { - return toInstance(sym, pre.baseType(clazz).prefix(), clazz.owner()); - } - } - - Type toPrefix(Symbol sym, Type pre, Symbol clazz) { - //System.out.println(this + ".toPrefix(" + sym + "," + pre + "," + clazz + ")");//DEBUG - if (pre == NoType || clazz.kind != CLASS) - return this; - else if (sym.isSubClass(clazz) && - pre.widen().symbol().isSubClass(sym)) - return pre; - else - return toPrefix(sym, pre.baseType(clazz).prefix(), clazz.owner()); - } - - /** This type as seen from prefix `pre' and class `clazz'. This means: - * Replace all thistypes of `clazz' or one of its subclasses by `pre' - * and instantiate all parameters by arguments of `pre'. - * Proceed analogously for thistypes referring to outer classes. - */ - public Type asSeenFrom(Type pre, Symbol clazz) { - //System.out.println("computing asseenfrom of " + this + " with " + pre + "," + clazz);//DEBUG - return new AsSeenFromMap(pre, clazz).apply(this); - } - - /** Types `these' as seen from prefix `pre' and class `clazz'. - */ - public static Type[] asSeenFrom(Type[] these, Type pre, Symbol clazz) { - return new AsSeenFromMap(pre, clazz).map(these); - } - - /** The info of `sym', seen as a member of this type. - */ - public Type memberInfo(Symbol sym) { - return sym.info().asSeenFrom(this, sym.owner()); - } - - /** The type of `sym', seen as a member of this type. - */ - public Type memberType(Symbol sym) { - return sym.type().asSeenFrom(this, sym.owner()); - } - - /** The stabilized type of `sym', seen as a member of this type. - */ - public Type memberStabilizedType(Symbol sym) { - return sym.isStable() && this.isStable() - ? Type.singleTypeMethod(this, sym) - : this.memberType(sym); - } - - /** The low bound of `sym', seen as a member of this type. - */ - public Type memberLoBound(Symbol sym) { - return sym.loBound().asSeenFrom(this, sym.owner()); - } - - /** The view bound of `sym', seen as a member of this type. - */ - public Type memberVuBound(Symbol sym) { - return sym.vuBound().asSeenFrom(this, sym.owner()); - } - -// Substitutions --------------------------------------------------------------- - - /** A common map superclass for symbol/symbol and type/symbol substitutions. - */ - public static abstract class SubstMap extends Map { - private Symbol[] from; - - SubstMap(Symbol[] from) { - this.from = from; - } - - public boolean matches(Symbol sym1, Symbol sym2) { - return sym1 == sym2; - } - - /** Produce replacement type - * @param i The index in `from' of the symbol to be replaced. - * @param fromtp The type referring to this symbol. - */ - protected abstract Type replacement(int i, Type fromtp); - - /** Produce new substitution where some symbols are excluded. - * @param newfrom The new array of from symbols (without excluded syms) - * @param excluded The array of excluded sysmbols - */ - protected abstract SubstMap exclude(Symbol[] newfrom, Symbol[] excluded); - - public Type apply(Type t) { - switch (t) { - case TypeRef(NoPrefix, Symbol sym, Type[] args): - for (int i = 0; i < from.length; i++) { - if (matches(sym, from[i])) return replacement(i, t); - } - break; - case SingleType(NoPrefix, Symbol sym): - for (int i = 0; i < from.length; i++) { - if (matches(sym, from[i])) return replacement(i, t); - } - break; - case PolyType(Symbol[] tparams, Type result): - Symbol[] from1 = excludeSyms(from, tparams, from); - if (from1 != from) { - SubstMap f = exclude(from1, tparams); - Symbol[] tparams1 = f.map(tparams); - Type result1 = f.apply(result); - if (tparams1 != tparams) - result1 = result1.subst(tparams, tparams1); - if (tparams1 == tparams && result1 == result) return t; - else return PolyType(tparams1, result1); - } - } - return map(t); - } - //where - private boolean contains1(Symbol[] syms, Symbol sym) { - int i = 0; - while (i < syms.length && syms[i] != sym) i++; - return i < syms.length; - } - - private int nCommon(Symbol[] from, Symbol[] tparams) { - int cnt = 0; - for (int i = 0; i < from.length; i++) { - if (contains1(tparams, from[i])) cnt++; - } - return cnt; - } - - private Symbol[] excludeSyms(Symbol[] from, Symbol[] tparams, Symbol[] syms) { - int n = nCommon(from, tparams); - if (n == 0) { - return syms; - } else { - Symbol[] syms1 = new Symbol[syms.length - n]; - int j = 0; - for (int i = 0; i < from.length; i++) { - if (!contains1(tparams, from[i])) syms1[j++] = syms[i]; - } - return syms1; - } - } - - private Type[] excludeTypes(Symbol[] from, Symbol[] tparams, Type[] types) { - int n = nCommon(from, tparams); - if (n == 0) { - return types; - } else { - Type[] types1 = new Type[types.length - n]; - int j = 0; - for (int i = 0; i < from.length; i++) { - if (!contains1(tparams, from[i])) types1[j++] = types[i]; - } - return types1; - } - } - } - - /** A map for symbol/symbol substitutions - */ - public static class SubstSymMap extends SubstMap { - Symbol[] to; - protected SubstSymMap(Symbol[] from, Symbol[] to) { - super(from); - this.to = to; - } - protected Type replacement(int i, Type fromtp) { - switch (fromtp) { - case TypeRef(Type pre, Symbol sym, Type[] args): - return typeRef(pre, to[i], args); - case SingleType(Type pre, Symbol sym): - return singleType(pre, to[i]); - default: - throw new ApplicationError(); - } - } - protected SubstMap exclude(Symbol[] newfrom, Symbol[] excluded) { - return new SubstSymMap(newfrom, excludeSyms(from, excluded, to)); - } - } - - /** A map for type/symbol substitutions - */ - public static class SubstTypeMap extends SubstMap { - Type[] to; - public SubstTypeMap(Symbol[] from, Type[] to) { - super(from); - this.to = to; - } - public Type replacement(int i, Type fromtp) { - return to[i]; - } - public SubstMap exclude(Symbol[] newfrom, Symbol[] excluded) { - return new SubstTypeMap(newfrom, excludeTypes(from, excluded, to)); - } - } - - - /** A map for symbol/symbol substitutions which, instead of - * cloning parameters, updates their symbol's types. - */ - public static class UpdateSubstSymMap extends SubstSymMap { - protected UpdateSubstSymMap(Symbol[] from, Symbol[] to) { - super(from, to); - } - public Type apply(Type t) { - switch (t) { - case PolyType(Symbol[] params, Type result): - // !!! Also update loBounds? How? loBound can only be set! - for (int i = 0; i < params.length; i++) { - Type tp = params[i].nextType(); - Type tp1 = apply(tp); - if (tp != tp1) params[i].updateInfo(tp1); - } - Type result1 = apply(result); - if (result1 == result) return t; - else return Type.PolyType(params, result1); - case MethodType(Symbol[] params, Type result): - for (int i = 0; i < params.length; i++) { - Type tp = params[i].nextType(); - Type tp1 = apply(tp); - if (tp != tp1) params[i].updateInfo(tp1); - } - Type result1 = apply(result); - if (result1 == result) return t; - else return Type.MethodType(params, result1); - default: - return super.apply(t); - } - } - public Symbol map(Symbol sym, boolean dontClone) { return sym; } - public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; } - public Scope map(Scope s) { return s; } - } - - /** Returns the given non-updating symbol/symbol substitution. */ - public static Map getSubst(Symbol[] from, Symbol[] to) { - return getSubst(from, to, false); - } - - /** Returns the given (updating?) symbol/symbol substitution. */ - public static Map getSubst(Symbol[] from, Symbol[] to, boolean update) { - if (from.length == 0 && to.length == 0) return IdMap; - if (update) return new UpdateSubstSymMap(from, to); - return new SubstSymMap(from, to); - } - - /** Returns the given non-updating symbol/type substitution. */ - public static Map getSubst(Symbol[] from, Type[] to) { - if (from.length == 0 && to.length == 0) return IdMap; - return new SubstTypeMap(from, to); - } - - /** Substitute symbols `to' for occurrences of symbols `from' in this type. - */ - public Type subst(Symbol[] from, Symbol[] to) { - if (to.length != 0 && from != to) {//!!! - assert from.length == to.length - : this + ": " + from.length + " != " + to.length; - return new SubstSymMap(from, to).apply(this); - } else return this; - } - - /** Substitute symbols `to' for occurrences of symbols `from' in these types. - */ - public static Type[] subst(Type[] these, Symbol[] from, Symbol[] to) { - if (these.length != 0 && to.length != 0 && from != to) { - assert from.length == to.length; - return new SubstSymMap(from, to).map(these); - } else return these; - } - - /** Substitute types `to' for occurrences of symbols `from' in this type. - */ - public Type subst(Symbol[] from, Type[] to) { - if (to.length != 0) { - assert from.length == to.length - : this + ": " + Debug.show(from) + " <> " + ArrayApply.toString(to); - return new SubstTypeMap(from, to).apply(this); - } else return this; - } - - /** Substitute types `to' for occurrences of symbols `from' in these types. - */ - public static Type[] subst(Type[] these, Symbol[] from, Type[] to) { - if (these.length != 0 && to.length != 0) { - assert from.length == to.length; - return new SubstTypeMap(from, to).map(these); - } else return these; - } - - /** - * A map that substitutes ThisTypes of a given class by a given - * type. All occurrences of the type parameters of the given class - * are replaced by the type arguments extracted from the given - * type. Furthermore, the prefixes of the given type are used to - * substitute, in the same way, the ThisTypes of the outer classes - * of the given class. - * - * object Foo { - * class C[D] { class I[J]; } - * val c: C[Int] = new C[Int]; - * class M[N] extends c.I[N]; - * } - * - * In the code above, a ThisTypeMap of class "I" and type - * "ThisType(M)", would do the following substitutions: - * - * - ThisType(I) -> ThisType(M) - * - TypeRef(_, J, _) -> TypeRef(_, N, -) - * - ThisType(C) -> SingleType(ThisType(Foo), c) - * - TypeRef(_, D, _) -> TypeRef(_, Int, _) - */ - private static class ThisTypeMap extends Map { - - private static Map create(Symbol clasz, Type type) { - HashMap subst = getSubst(clasz, type, 0); - return subst == null ? IdMap : new ThisTypeMap(subst); - } - - private static HashMap getSubst(Symbol clasz, Type type, int capacity){ - switch (type) { - case NoPrefix: - return getSubst(capacity); - case ThisType(Symbol symbol): - if (symbol == clasz) return getSubst(capacity); - } - Type base = type.baseType(clasz); - switch (base) { - case TypeRef(Type prefix, Symbol symbol, Type[] args): - capacity += 1 + args.length; - HashMap subst = getSubst(clasz.owner(), prefix, capacity); - subst.put(clasz, type); - Symbol[] params = clasz.typeParams(); - assert symbol == clasz && args.length == params.length: - type + " @ " + Debug.show(clasz) + " -> " + base; - for (int i = 0; i < params.length; i++) { - assert params[i].isParameter(): Debug.show(params[i]); - subst.put(params[i], args[i]); - } - return subst; - default: - throw Debug.abort("illegal case", - type + " @ " + Debug.show(clasz) + " -> " + base); - } - } - - private static HashMap getSubst(int capacity) { - return capacity == 0 ? null : new HashMap(capacity); - } - - private final HashMap/*<Symbol,Type>*/ subst; - - private ThisTypeMap(HashMap subst) { - this.subst = subst; - } - - public Type apply(Type type) { - switch (type) { - case ThisType(Symbol symbol): - Object lookup = subst.get(symbol); - if (lookup == null) break; - return (Type)lookup; - case TypeRef(NoPrefix, Symbol symbol, Type[] args): - if (!symbol.isParameter()) break; - assert args.length == 0: type; - Object lookup = subst.get(symbol); - if (lookup == null) break; - return (Type)lookup; - } - return map(type); - } - - public String toString() { - return subst.toString(); - } - - } - - /** Returns a ThisTypeMap of given class and type. */ - public static Map getThisTypeMap(Symbol clasz, Type type) { - return ThisTypeMap.create(clasz, type); - } - - /** A map for substitutions of thistypes. - */ - public static class SubstThisMap extends Map { - Symbol from; - Type to; - public SubstThisMap(Symbol from, Type to) { - this.from = from; - this.to = to; - } - public SubstThisMap(Symbol oldSym, Symbol newSym) { - this(oldSym, newSym.thisType()); - } - public Type apply(Type type) { - switch (type) { - case ThisType(Symbol sym): - return sym == from ? to : type; - default: - return map(type); - } - } - } - - public Type substThis(Symbol from, Type to) { - return new SubstThisMap(from, to).apply(this); - } - - public static Type[] substThis(Type[] these, Symbol from, Type to) { - return new SubstThisMap(from, to).map(these); - } - - static class ContainsMap extends Map { - boolean result = false; - Symbol sym; - ContainsMap(Symbol sym) { - this.sym = sym; - } - public Type apply(Type t) { - if (!result) { - switch (t) { - case TypeRef(Type pre, Symbol sym1, Type[] args): - if (sym == sym1) result = true; - else { map(pre); map(args); } - break; - case SingleType(Type pre, Symbol sym1): - map(pre); - if (sym == sym1) result = true; - break; - default: - map(t); - } - } - return t; - } - } - - /** Does this type contain symbol `sym'? - */ - public boolean contains(Symbol sym) { - ContainsMap f = new ContainsMap(sym); - f.apply(this); - return f.result; - } - - /** Does this type contain any of the symbols `syms'? - */ - public boolean containsSome(Symbol[] syms) { - for (int i = 0; i < syms.length; i++) - if (contains(syms[i])) return true; - return false; - } - -// Cloning --------------------------------------------------------------- - - /** Returns a shallow copy of the given array. */ - public static Type[] cloneArray(Type[] array) { - return cloneArray(0, array, 0); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items. - */ - public static Type[] cloneArray(int prefix, Type[] array) { - return cloneArray(prefix, array, 0); - } - - /** - * Returns a shallow copy of the given array suffixed by "suffix" - * null items. - */ - public static Type[] cloneArray(Type[] array, int suffix) { - return cloneArray(0, array, suffix); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items and suffixed by "suffix" null items. - */ - public static Type[] cloneArray(int prefix, Type[] array, int suffix) { - assert prefix >= 0 && suffix >= 0: prefix + " - " + suffix; - int size = prefix + array.length + suffix; - if (size == 0) return EMPTY_ARRAY; - Type[] clone = new Type[size]; - for (int i = 0; i < array.length; i++) clone[prefix + i] = array[i]; - return clone; - } - - /** Returns the concatenation of the two arrays. */ - public static Type[] concat(Type[] array1, Type[] array2) { - if (array1.length == 0) return array2; - if (array2.length == 0) return array1; - Type[] clone = cloneArray(array1.length, array2); - for (int i = 0; i < array1.length; i++) clone[i] = array1[i]; - return clone; - } - - /** - * Clones a type i.e. returns a new type where all symbols in - * MethodTypes and PolyTypes and CompoundTypes have been cloned. - */ - public Type cloneType(Symbol oldOwner, Symbol newOwner) { - SymbolCloner cloner = new SymbolCloner(); - cloner.owners.put(oldOwner, newOwner); - return cloner.cloneType(this); - } - - /** - * Clones a type i.e. returns a new type where all symbols in - * MethodTypes and PolyTypes have been cloned. This method - * performs no substitution on the type of the cloned symbols. - * Typically, the type of those symbols will be fixed later by - * applying some Map.applyParams method to the returned type. - */ - public Type cloneTypeNoSubst(SymbolCloner cloner) { - switch (this) { - - case MethodType(Symbol[] vparams, Type result): - Symbol[] clones = cloner.cloneSymbols(vparams); - return Type.MethodType(clones, result.cloneTypeNoSubst(cloner)); - - case PolyType(Symbol[] tparams, Type result): - Symbol[] clones = cloner.cloneSymbols(tparams); - return Type.PolyType(clones, result.cloneTypeNoSubst(cloner)); - - default: - return this; - } - } - - -// Comparisons ------------------------------------------------------------------ - - /** Type relations */ - public static class Relation { - public case SubType; // this SubType that <=> this.isSubType(that) - public case SameType; // this SameType that <=> this.isSameAs(that) - public case SuperType; // this SuperType that <=> that.isSubType(this) - - public String toString() { - return toString(false); - } - public String toString(boolean negate) { - switch (this) { - case SubType : return negate ? "!<=" : "<="; - case SameType : return negate ? "!==" : "="; - case SuperType: return negate ? "!>=" : ">="; - default : throw Debug.abort("unknown relation", this); - } - } - } - - /** Is this type in given relation to that type? - */ - public boolean compareTo(Type that, Relation relation) { - switch (relation) { - case SubType : return this.isSubType(that); - case SameType : return this.isSameAs(that); - case SuperType: return that.isSubType(this); - default : throw Debug.abort("unknown relation", relation); - } - } - - /** Is this type a subtype of that type? - */ - public boolean isSubType(Type that) { - if (explainSwitch) { - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(this + " < " + that + "?"); - indent++; - } - boolean result = isSubType0(that); - if (explainSwitch) { - indent--; - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(result); - } - return result; - } - - public boolean isSubType0(Type that) { - if (this == that) return true; - - switch (this) { - case ErrorType: - case AnyType: - return true; - } - - switch (that) { - case ErrorType: - case AnyType: - return true; - - case NoType: - case NoPrefix: - return false; - - case ThisType(_): - case SingleType(_, _): - switch (this) { - case ThisType(_): - case SingleType(_, _): - return this.isSameAs(that); - default: - if (this.isSameAs(that)) return true; - } - break; - - case ConstantType(_, _): - switch (this) { - case ConstantType(Type base, _): - return this.isSameAs(that) || base.isSubType(that); - } - break; - - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - switch (this) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym == sym1 && pre.isSubType(pre1) && - isSubArgs(args, args1, sym.typeParams()) - || - sym.kind == TYPE && pre.memberInfo(sym).isSubType(that)) - return true; - break; - } - if (sym1.kind == CLASS) { - Type base = this.baseType(sym1); - if (this != base && base.isSubType(that)) - return true; - } - break; - - case CompoundType(Type[] parts1, Scope members1): - int i = 0; - while (i < parts1.length && isSubType(parts1[i])) i++; - if (i == parts1.length && specializes(members1)) - return true; - break; - - case MethodType(Symbol[] ps1, Type res1): - switch (this) { - case MethodType(Symbol[] ps, Type res): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) { - Symbol p1 = ps1[i]; - Symbol p = ps[i]; - if (!p1.type().isSameAs(p.type()) || - (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED))) - return false; - } - return res.isSubType(res1); - } - break; - - case PolyType(Symbol[] ps1, Type res1): - switch (this) { - case PolyType(Symbol[] ps, Type res): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) - if (!ps1[i].info().subst(ps1, ps).isSubType(ps[i].info()) || - !ps[i].loBound().isSubType(ps1[i].loBound().subst(ps1, ps)) || - !ps1[i].vuBound().subst(ps1, ps).isSubType(ps[i].vuBound())) - return false; - return res.isSubType(res1.subst(ps1, ps)); - } - break; - - case OverloadedType(Symbol[] alts1, Type[] alttypes1): - for (int i = 0; i < alttypes1.length; i++) { - if (!isSubType(alttypes1[i])) - return false; - } - return true; - - case UnboxedType(int tag1): - switch (this) { - case UnboxedType(int tag): - return tag == tag1; - } - break; - - case UnboxedArrayType(Type elemtp1): - switch (this) { - case UnboxedArrayType(Type elemtp): - return elemtp.isSubType(elemtp1); - } - break; - - case TypeVar(Type origin, Constraint constr): - //todo: should we test for equality with origin? - if (constr.inst != NoType) { - return this.isSubType(constr.inst); - } else { - constr.lobounds = new List(this, constr.lobounds); - return true; - } - - default: - throw new ApplicationError(this + " <: " + that); - } - - switch (this) { - case NoType: - case NoPrefix: - return false; - case ThisType(_): - case SingleType(_, _): - if (this.isSameAs(that)) return true; - if (this.singleDeref().isSubType(that)) return true; - break; - case ConstantType(_, _): - if (this.singleDeref().isSubType(that)) return true; - break; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) { - return constr.inst.isSubType(that); - } else { - constr.hibounds = new List(that, constr.hibounds); - return true; - } - - case TypeRef(_, Symbol sym, _): - switch (that) { - case TypeRef(_, Symbol sym1, _): - if (sym1.kind == TYPE && this.isSubType(that.loBound())) - return true; - } - if (sym == Global.instance.definitions.ALL_CLASS) - return that.isSubType(Global.instance.definitions.ANY_TYPE()); - else if (sym == Global.instance.definitions.ALLREF_CLASS) - return - that.symbol() == Global.instance.definitions.ANY_CLASS || - (that.symbol() != Global.instance.definitions.ALL_CLASS && - that.isSubType(Global.instance.definitions.ANYREF_TYPE())); - break; - - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alttypes.length; i++) { - if (alttypes[i].isSubType(that)) return true; - } - break; - - case CompoundType(Type[] parts, Scope members): - int i = 0; - while (i < parts.length) { - if (parts[i].isSubType(that)) return true; - i++; - } - break; - - case UnboxedArrayType(_): - if (Global.instance.definitions.OBJECT_TYPE().isSubType(that)) - return true; - // !!! we should probably also test for Clonable, Serializable, ... - } - - return false; - } - - /** Are types `these' subtypes of corresponding types `those'? - */ - public static boolean isSubType(Type[] these, Type[] those) { - if (these.length != those.length) return false; - for (int i = 0; i < these.length; i++) { - if (!these[i].isSubType(those[i])) return false; - } - return true; - } - - /** Are types `these' arguments types conforming to corresponding types `those'? - */ - static boolean isSubArgs(Type[] these, Type[] those, Symbol[] tparams) { - if (these.length != those.length) return false; - for (int i = 0; i < these.length; i++) { - if ((tparams[i].flags & COVARIANT) != 0) { - if (!these[i].isSubType(those[i])) return false; - } else if ((tparams[i].flags & CONTRAVARIANT) != 0) { - //System.out.println("contra: " + these[i] + " " + those[i] + " " + those[i].isSubType(these[i]));//DEBUG - if (!those[i].isSubType(these[i])) return false; - } else { - if (!these[i].isSameAs(those[i])) return false; - } - } - return true; - } - - public static boolean isSubSet(Type[] alts, Type[] alts1) { - for (int i = 0; i < alts.length; i++) { - int j = 0; - while (j < alts1.length && !alts1[j].isSameAs(alts[i])) j++; - if (j == alts1.length) return false; - } - return true; - } - - /** Does this type implement all symbols in scope `s' with same or stronger types? - */ - public boolean specializes(Scope s) { - for (Scope.SymbolIterator it = s.iterator(); - it.hasNext();) { - if (!specializes(it.next())) return false; - } - return true; - } - - /** Does this type implement symbol `sym1' with same or stronger type? - */ - public boolean specializes(Symbol sym1) { - if (explainSwitch) { - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(this + " specializes " + sym1 + "?"); - indent++; - } - boolean result = specializes0(sym1); - if (explainSwitch) { - indent--; - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(result); - } - return result; - } - - private boolean specializes0(Symbol sym1) { - Type self = narrow(); - Symbol[] tparams = symbol().typeParams(); - Type[] targs = typeArgs(); - Symbol sym = lookup(sym1.name); - return - sym.kind != NONE && - (sym == sym1 - || - (sym.kind == sym1.kind || sym1.kind == TYPE) && - self.memberInfo(sym).subst(tparams, targs) - .isSubType(sym1.info().substThis(sym1.owner(), self)) && - sym1.loBound().substThis(sym1.owner(), self) - .isSubType(self.memberLoBound(sym).subst(tparams, targs)) && - self.memberVuBound(sym).subst(tparams, targs) - .isSubType(sym1.vuBound().substThis(sym1.owner(), self)) - || - (sym.kind == TYPE && sym1.kind == ALIAS && - sym1.info().unalias().isSameAs(sym.type()))); - } - - /** Is this type the same as that type? - */ - public boolean isSameAs(Type that) { - if (explainSwitch) { - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(this + " = " + that + "?"); - indent++; - } - boolean result = isSameAs0(that); - if (explainSwitch) { - indent--; - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(result); - } - return result; - } - - public boolean isSameAs0(Type that) { - if (this == that) return true; - - switch (this) { - case ErrorType: - case AnyType: - return true; - - case ThisType(Symbol sym): - switch (that) { - case ThisType(Symbol sym1): - return sym == sym1; - case SingleType(Type pre1, Symbol sym1): - return sym1.isModule() - && sym == sym1.moduleClass() - && sym.owner().thisType().isSameAs(pre1) - || - this.singleDeref().isSingletonType() && - this.singleDeref().isSameAs(that) - || - that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - deAlias(that) != that && - this.isSameAs(deAlias(that)); - default: - if (deAlias(this) != this) - return deAlias(this).isSameAs(that); - } - break; - - case SingleType(Type pre, Symbol sym): - switch (that) { - case SingleType(Type pre1, Symbol sym1): - return sym == sym1 && pre.isSameAs(pre1) - || - this.singleDeref().isSingletonType() && - this.singleDeref().isSameAs(that) - || - that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - (deAlias(this) != this || deAlias(that) != that) && - deAlias(this).isSameAs(deAlias(that)); - case ThisType(Symbol sym1): - return sym.isModule() - && sym.moduleClass() == sym1 - && pre.isSameAs(sym1.owner().thisType()) - || - this.singleDeref().isSingletonType() && - this.singleDeref().isSameAs(that) - || - that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - deAlias(this) != this && - deAlias(this).isSameAs(that); - default: - if (deAlias(this) != this) - return deAlias(this).isSameAs(that); - } - break; - - case ConstantType(Type base, AConstant value): - switch (that) { - case ConstantType(Type base1, AConstant value1): - return base.isSameAs(base1) && value.equals(value1); - } - break; - - case TypeRef(Type pre, Symbol sym, Type[] args): - switch (that) { - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - if (sym == sym1 && pre.isSameAs(pre1) && isSameAs(args, args1)) - return true; - } - break; - - case CompoundType(Type[] parts, Scope members): - switch (that) { - case CompoundType(Type[] parts1, Scope members1): - if (parts.length != parts1.length) return false; - for (int i = 0; i < parts.length; i++) - if (!parts[i].isSameAs(parts1[i])) return false; - return isSameAs(members, members1); - } - break; - - case MethodType(Symbol[] ps, Type res): - switch (that) { - case MethodType(Symbol[] ps1, Type res1): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) { - Symbol p1 = ps1[i]; - Symbol p = ps[i]; - if (!p1.type().isSameAs(p.type()) || - (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED))) - return false; - } - return res.isSameAs(res1); - } - break; - - case PolyType(Symbol[] ps, Type res): - switch (that) { - case PolyType(Symbol[] ps1, Type res1): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) - if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) || - !ps1[i].loBound().subst(ps1, ps).isSameAs(ps[i].loBound()) || - !ps1[i].vuBound().subst(ps1, ps).isSameAs(ps[i].vuBound())) - return false; - return res.isSameAs(res1.subst(ps1, ps)); - } - break; - - case OverloadedType(Symbol[] alts, Type[] alttypes): - switch (that) { - case OverloadedType(Symbol[] alts1, Type[] alttypes1): - return isSubSet(alttypes1, alttypes) - && isSubSet(alttypes, alttypes1); - } - break; - - case UnboxedType(int kind): - switch (that) { - case UnboxedType(int kind1): - return kind == kind1; - } - break; - - case UnboxedArrayType(Type elemtp): - switch (that) { - case UnboxedArrayType(Type elemtp1): - return elemtp.isSameAs(elemtp1); - } - break; - } - - switch (that) { - case ErrorType: - case AnyType: - return true; - case NoType: - case NoPrefix: - return false; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.isSameAs(this); - else return constr.instantiate(this.any2typevar()); - case ThisType(_): - case SingleType(_, _): - if (deAlias(that) != that) - return this.isSameAs(deAlias(that)); - } - - switch (this) { - case NoType: - case NoPrefix: - return false; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.isSameAs(that); - else return constr.instantiate(that.any2typevar()); - } - - return false; - } - //where - - static Type deAlias(Type tp) { - switch (tp) { - case ThisType(_): - case SingleType(_, _): - Type tp1 = tp.singleDeref(); - if (tp1.isStable()) return deAlias(tp1); - } - return tp; - } - - /** Are types `these' the same as corresponding types `those'? - */ - public static boolean isSameAs(Type[] these, Type[] those) { - if (these.length != those.length) return false; - for (int i = 0; i < these.length; i++) { - if (!these[i].isSameAs(those[i])) return false; - } - return true; - } - - /** Do scopes `s1' and `s2' define he same symbols with the same kinds and infos? - */ - public boolean isSameAs(Scope s1, Scope s2) { - return isSubScope(s1, s2) && isSubScope(s2, s1); - } - - /** Does scope `s1' define all symbols of scope `s2' with the same kinds and infos? - */ - private boolean isSubScope(Scope s1, Scope s2) { - for (Scope.SymbolIterator it = s2.iterator(); it.hasNext(); ) { - Symbol sym2 = it.next(); - // todo: handle overloaded - Symbol sym1 = s1.lookup(sym2.name); - if (sym1.kind != sym2.kind || - !sym1.info().isSameAs( - sym2.info().substThis( - sym2.owner(), sym1.owner().thisType())) || - !sym1.loBound().isSameAs( - sym2.loBound().substThis( - sym2.owner(), sym1.owner().thisType())) || - !sym1.vuBound().isSameAs( - sym2.vuBound().substThis( - sym2.owner(), sym1.owner().thisType()))) - return false; - } - return true; - } - - boolean isSameAsAll(Type[] tps) { - int i = 1; - while (i < tps.length && isSameAs(tps[i])) i++; - return i == tps.length; - } - - /** Map every occurrence of AnyType to a fresh type variable. - */ - public static Map any2typevarMap = new Map() { - public Type apply(Type t) { return t.any2typevar(); } - }; - - public Type any2typevar() { - switch (this) { - case AnyType: - return TypeVar(this, new Constraint()); - default: - return any2typevarMap.map(this); - } - } - - /** Does this type match type `tp', so that corresponding symbols with - * the two types would be taken to override each other? - */ - public boolean overrides(Type tp) { - switch (this) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alttypes.length; i++) { - if (alttypes[i].overrides(tp)) return true; - } - return false; - default: - switch (tp) { - case MethodType(Symbol[] ps1, Type res1): - switch (this) { - case MethodType(Symbol[] ps, Type res): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) { - Symbol p1 = ps1[i]; - Symbol p = ps[i]; - if (!p1.type().isSameAs(p.type()) || - (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED))) - return false; - } - return res.overrides(res1); - } - return false; - - case PolyType(Symbol[] ps1, Type res1): - switch (this) { - case PolyType(Symbol[] ps, Type res): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) - if (!ps1[i].info().subst(ps1, ps).isSubType(ps[i].info()) || - !ps[i].loBound().isSubType(ps1[i].loBound().subst(ps1, ps)) || - !ps1[i].vuBound().subst(ps1, ps).isSubType(ps[i].vuBound())) - return false; - return res.overrides(res1.subst(ps1, ps)); - } - return false; - - case OverloadedType(_, _): - throw new ApplicationError("overrides inapplicable for " + tp); - - default: - switch (this) { - case MethodType(_, _): case PolyType(_, _): return false; - default: return true; - } - } - } - } - -// Closures and Least Upper Bounds --------------------------------------------------- - - /** The closure of this type, i.e. the widened type itself followed by all - * its direct and indirect (pre-) base types, sorted by Symbol.isLess(). - */ - public Type[] closure() { - switch (this.widen().unalias()) { - case TypeRef(Type pre, Symbol sym, Type[] args): - return subst( - asSeenFrom(sym.closure(), pre, sym.owner()), - sym.typeParams(), args); - - case CompoundType(Type[] parts, Scope members): -/* - if (symbol().isCompoundSym()) { - Type[][] closures = new Type[parts.length][]; - for (int i = 0; i < parts.length; i++) - closures[i] = parts[i].closure(); - return union(closures); - } else { -*/ - return symbol().closure(); - - default: - return new Type[]{this}; - } - } - - /** return union of array of closures. It is assumed that - * for any two base types with the same class symbols the later one - * is a subtype of the former. - */ - static private Type[] union(Type[][] closures) { - if (closures.length == 1) return closures[0]; // fast special case - int[] index = new int[closures.length]; - int totalsize = 0; - for (int i = 0; i < index.length; i++) { - index[i] = 0; - totalsize = totalsize + closures[i].length; - } - Type[] res = new Type[totalsize]; - int j = 0; - - while (true) { - // find minimal element - Type min = null; - for (int i = 0; i < index.length; i++) { - if (index[i] < closures[i].length) { - Type cltype = closures[i][index[i]]; - if (min == null || - cltype.symbol().isLess(min.symbol()) || - cltype.symbol() == min.symbol()) { - min = cltype; - } - } - } - if (min == null) break; - - res[j] = min; - j = j + 1; - - // bump all indices that start with minimal element - for (int i = 0; i < index.length; i++) { - if (index[i] < closures[i].length && - closures[i][index[i]].symbol() == min.symbol()) - index[i] = index[i] + 1; - } - } - Type[] result = new Type[j]; - System.arraycopy(res, 0, result, 0, j); - return result; - } - - /** return intersection of non-empty array of closures - */ - static private Type[] intersection(Type[][] closures) { - if (closures.length == 1) return closures[0]; // fast special case - int[] index = new int[closures.length]; - Type[] mintypes = new Type[closures.length]; - int minsize = Integer.MAX_VALUE; - for (int i = 0; i < index.length; i++) { - index[i] = 0; - if (closures[i].length < minsize) minsize = closures[i].length; - } - Type[] res = new Type[minsize]; - int j = 0; - - L: - while (true) { - // find minimal element - Symbol minsym = null; - for (int i = 0; i < index.length; i++) { - if (index[i] == closures[i].length) break L; - Symbol clsym = closures[i][index[i]].symbol(); - if (minsym == null || clsym.isLess(minsym)) minsym = clsym; - } - - boolean agree = true; - // bump all indices that start with minimal element - for (int i = 0; i < index.length; i++) { - Type cltype = closures[i][index[i]]; - if (cltype.symbol() == minsym) { - mintypes[i] = cltype; - index[i] = index[i] + 1; - } else { - agree = false; - } - } - if (agree) { - Type mintype = argLub(mintypes); - if (mintype.symbol().kind == CLASS) { - res[j] = mintype; - j = j + 1; - } - } - } - Type[] result = new Type[j]; - System.arraycopy(res, 0, result, 0, j); - return result; - } - - /** same as lub, but all types are instances of the same class, - * possibly with different prefixes and arguments. - */ - //todo: catch lubs not within bounds. - static Type argLub(Type[] tps) { - tps = elimRedundant(tps, true); - if (tps.length == 1) return tps[0]; - - Type pre = tps[0].prefix(); - Symbol sym = tps[0].symbol(); - Symbol[] tparams = sym.typeParams(); - Type[] args = new Type[tparams.length]; - Type[][] argss = new Type[args.length][tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - assert sym == sym1; - assert args1.length == args.length; - if (!pre.isSameAs(pre1)) return NoType; - for (int j = 0; j < args1.length; j++) - argss[j][i] = args1[j]; - break; - case ErrorType: - return ErrorType; - default: - assert false : tps[i]; - } - } - for (int j = 0; j < args.length; j++) { - if ((tparams[j].flags & COVARIANT) != 0) - args[j] = lub(argss[j]); - else if ((tparams[j].flags & CONTRAVARIANT) != 0) - args[j] = glb(argss[j]); - else return NoType; - } - return typeRef(pre, sym, args); - } - - /** The frontier of a closure C is the minimal set of types such that - * the union of the closures of these types equals C. - */ - static private Type[] frontier(Type[] closure) { - Type[] front = new Type[closure.length]; - int j = 0; - for (int i = 0; i < closure.length; i++) { - int k = 0; - Type tp = closure[i]; - while (k < j && !front[k].symbol().isSubClass(tp.symbol())) - k++; - if (k == j) { - front[j] = tp; - j++; - } - } - Type[] result = new Type[j]; - System.arraycopy(front, 0, result, 0, j); - return result; - } - - /** remove types that are subtypes of some other type. - */ - static private Type[] elimRedundant(Type[] tps, boolean elimLower) { - Type.List tl = Type.List.EMPTY; - int nredundant = 0; - boolean[] redundant = new boolean[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case ErrorType: - return new Type[]{ErrorType}; - case MethodType(_, _): - case PolyType(_, _): - case OverloadedType(_, _): - return new Type[]{NoType}; - default: - assert tps[i].isObjectType(): tps[i]; - for (int j = 0; j < i && !redundant[i]; j++) { - if (!redundant[j]) { - if (tps[i].isSubType(tps[j])) { - redundant[elimLower ? i : j] = true; - nredundant++; - } else if (tps[j].isSubType(tps[i])) { - redundant[elimLower ? j : i] = true; - nredundant++; - } - } - } - } - } - - if (nredundant != 0) { - Type[] tps1 = new Type[tps.length - nredundant]; - int n = 0; - for (int i = 0; i < tps.length; i++) { - if (!redundant[i]) tps1[n++] = tps[i]; - } - return tps1; - } else { - return tps; - } - } - - static int recCount = 0; - static boolean giveUp = false; - static int recLimit = 10; - - public static Type lub(Type[] tps) { - if (recCount == recLimit) { - giveUp = true; - return Global.instance.definitions.ANY_TYPE(); - } else { - recCount++; - Type result = lub0(tps); - recCount--; - if (recCount == 0) { - if (giveUp) { - giveUp = false; - throw new Error("failure to compute least upper bound of types " + - ArrayApply.toString(tps, "", " and ", ";\n") + - "an approximation is: " + result + ";\n" + - "additional type annotations are needed"); - } else { - giveUp = false; - } - } - return result; - } - } - - /** Return the least upper bound of non-empty array of types `tps'. - */ - public static Type lub0(Type[] tps) { - //for (int i = 0; i < recCount; i++) System.out.print(" "); System.out.println("lub" + ArrayApply.toString(tps));//debug - - if (tps.length == 0) return Global.instance.definitions.ALL_TYPE(); - - //If all types are method types with same parameters, - //compute lub of their result types. - switch (tps[0]) { - case PolyType(Symbol[] tparams, _): - return polyLub(tps, tparams); - case MethodType(Symbol[] vparams, _): - return methodLub(tps, vparams); - } - - // remove types that are subtypes of some other type. - tps = elimRedundant(tps, true); - if (tps.length == 1) return tps[0]; - - // singleDeref singletypes and try again - Type[] tps1 = tps; - for (int i = 0; i < tps.length; i++) { - Type tp1 = tps[i].singleDeref(); - if (tp1 != tps[i] && tps1 == tps) { - tps1 = new Type[tps.length]; - System.arraycopy(tps, 0, tps1, 0, i); - } - tps1[i] = tp1; - } - if (tps1 != tps) return lub0(tps1); - - // intersect closures and build frontier. - Type[][] closures = new Type[tps.length][]; - for (int i = 0; i < tps.length; i++) { - closures[i] = tps[i].closure(); - } - Type[] allBaseTypes = intersection(closures); - Type[] leastBaseTypes = frontier(allBaseTypes); - assert leastBaseTypes.length > 0 : ArrayApply.toString(tps); - - // add refinements where necessary - Scope members = new Scope(); - Type lubType = compoundTypeWithOwner(Symbol.NONE, leastBaseTypes, members); // !!! NONE - /* - Type lubThisType = lubType.narrow(); - //System.out.println("lubtype = " + lubType);//DEBUG - - Symbol[] rsyms = new Symbol[tps.length]; - Type[] rtps = new Type[tps.length]; - Type[] rlbs = new Type[tps.length]; - for (int i = 0; i < allBaseTypes.length; i++) { - for (Scope.SymbolIterator it = allBaseTypes[i].members().iterator(); - it.hasNext(); ) { - Symbol sym = it.next(); - Name name = sym.name; - if ((sym.flags & PRIVATE) == 0 && lubType.lookup(name) == sym) { - Type symType = memberTp(lubThisType, sym); - Type symLoBound = lubThisType.memberLoBound(sym); - int j = 0; - while (j < tps.length) { - rsyms[j] = tps[j].lookupNonPrivate(name); - if (rsyms[j] == sym) break; - rtps[j] = memberTp(tps[j], rsyms[j]) - .substThis(tps[j].symbol(), lubThisType); - rlbs[j] = tps[j].memberLoBound(rsyms[j]) - .substThis(tps[j].symbol(), lubThisType); - if (rtps[j].isSameAs(symType) && - rlbs[j].isSameAs(symLoBound)) break; - j++; - } - if (j == tps.length) { - if (Global.instance.debug) - System.out.println("refinement lub for " + - ArrayApply.toString(rsyms) + ":" + ArrayApply.toString(rtps));//debug - Symbol lubSym = lub(rsyms, rtps, rlbs, lubType.symbol()); - if (lubSym.kind != NONE && - !(lubSym.kind == sym.kind && - lubSym.info().isSameAs(symType) && - lubSym.loBound().isSameAs(symType))) - members.enter(lubSym); - } - } - } - } - //System.out.print("lub "); System.out.print(ArrayApply.toString(tps)); System.out.println(" = " + lubType);//DEBUG - */ - if (leastBaseTypes.length == 1 && members.isEmpty()) - return leastBaseTypes[0]; - else return lubType; - } - //where - private static Type memberTp(Type base, Symbol sym) { - return sym.kind == CLASS ? base.memberType(sym) : base.memberInfo(sym); - } - - private static Type polyLub(Type[] tps, Symbol[] tparams0) { - Type[][] hiboundss = new Type[tparams0.length][tps.length]; - Type[][] loboundss = new Type[tparams0.length][tps.length]; - Type[][] vuboundss = new Type[tparams0.length][tps.length]; - Type[] restps = new Type[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case PolyType(Symbol[] tparams, Type restp): - if (tparams.length == tparams0.length) { - for (int j = 0; j < tparams0.length; j++) { - hiboundss[j][i] = tparams[j].info() - .subst(tparams, tparams0); - loboundss[j][i] = tparams[j].loBound() - .subst(tparams, tparams0); - vuboundss[j][i] = tparams[j].vuBound() - .subst(tparams, tparams0); - } - restps[i] = restp.subst(tparams, tparams0); - } else { - return Type.NoType; - } - break; - default: - return Type.NoType; - } - } - Type[] hibounds = new Type[tparams0.length]; - Type[] lobounds = new Type[tparams0.length]; - Type[] vubounds = new Type[tparams0.length]; - for (int j = 0; j < tparams0.length; j++) { - hibounds[j] = glb(hiboundss[j]); - lobounds[j] = lub(loboundss[j]); - vubounds[j] = glb(vuboundss[j]); - } - Symbol[] tparams = new Symbol[tparams0.length]; - for (int j = 0; j < tparams.length; j++) { - tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE) - .setInfo(hibounds[j].subst(tparams0, tparams)) - .setLoBound(lobounds[j].subst(tparams0, tparams)) - .setVuBound(vubounds[j].subst(tparams0, tparams)); - } - return Type.PolyType(tparams, lub(restps).subst(tparams0, tparams)); - } - - private static Type methodLub(Type[] tps, Symbol[] vparams0) { - Type[] restps = new Type[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case MethodType(Symbol[] vparams, Type restp): - if (vparams.length != vparams0.length) - return Type.NoType; - for (int j = 0; j < vparams.length; j++) - if (!vparams[j].type().isSameAs(vparams0[j].type()) || - (vparams[j].flags & (DEF | REPEATED)) != - (vparams0[j].flags & (DEF | REPEATED))) - return Type.NoType; - restps[i] = restp; - } - } - Symbol[] vparams = new Symbol[vparams0.length]; - for (int j = 0; j < vparams.length; j++) { - vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE); - } - return Type.MethodType(vparams, lub(restps)); - } - - private static Symbol lub(Symbol[] syms, Type[] tps, Type[] lbs, Symbol owner) { - //System.out.println("lub" + ArrayApply.toString(syms));//DEBUG - int lubKind = syms[0].kind; - for (int i = 1; i < syms.length; i++) { - Symbol sym = syms[i]; - if (sym.isError()) return Symbol.NONE; - if (sym.isType() && sym.kind != lubKind) lubKind = TYPE; - } - if (lubKind == syms[0].kind && tps[0].isSameAsAll(tps)) { - return syms[0].cloneSymbol(); - } - - Type lubType = lub(tps); - if (lubType == Type.NoType) return Symbol.NONE; - Symbol lubSym; - switch (lubKind) { - case VAL: - lubSym = owner.newTerm(syms[0].pos, 0, syms[0].name); - break; - case TYPE: case ALIAS: case CLASS: - lubSym = owner.newAbstractType(syms[0].pos, 0, syms[0].name); - lubSym.setLoBound(glb(lbs)); - break; - default: - throw new ApplicationError(); - } - lubSym.setInfo(lubType.setOwner(lubSym)); - return lubSym; - } - - public static Type glb(Type[] tps) { - if (recCount == recLimit) { - giveUp = true; - return Global.instance.definitions.ALL_TYPE(); - } else { - recCount++; - Type result = glb0(tps); - recCount--; - if (recCount == 0) { - if (giveUp) { - giveUp = false; - throw new Error("failure to compute greatest lower bound of types " + - ArrayApply.toString(tps, "", " and ", ";\n") + - "an approximation is: " + result + ";\n" + - "additional type annotations are needed"); - } else { - giveUp = false; - } - } - return result; - } - } - - public static Type glb0(Type[] tps) { - if (tps.length == 0) return Global.instance.definitions.ANY_TYPE(); - - // step one: eliminate redunandant types; return if one one is left - tps = elimRedundant(tps, false); - if (tps.length == 1) return tps[0]; - - // step two: build arrays of all typerefs and all refinements - Type.List treftl = Type.List.EMPTY; - Type.List comptl = Type.List.EMPTY; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case TypeRef(_, _, _): - treftl = new Type.List(tps[i], treftl); - break; - case CompoundType(Type[] parents, Scope members): - if (!members.isEmpty()) - comptl = new Type.List(tps[i], comptl); - for (int j = 0; j < parents.length; j++) - treftl = new Type.List(parents[j], treftl); - break; - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return Global.instance.definitions.ALL_TYPE(); - } - } - - CompoundType glbType = compoundTypeWithOwner(Symbol.NONE, Type.EMPTY_ARRAY, new Scope()); // !!! NONE - Type glbThisType = glbType.narrow(); - - // step 3: compute glb of all refinements. - Scope members = Scope.EMPTY; - if (comptl != List.EMPTY) { - Type[] comptypes = comptl.toArrayReverse(); - Scope[] refinements = new Scope[comptypes.length]; - for (int i = 0; i < comptypes.length; i++) - refinements[i] = comptypes[i].members(); - if (!setGlb(glbType.members, refinements, glbThisType)) { - // refinements don't have lower bound, so approximate - // by AllRef - glbType.members = Scope.EMPTY; - treftl = new Type.List( - Global.instance.definitions.ALLREF_TYPE(), treftl); - } - } - - // eliminate redudant typerefs - Type[] treftypes = elimRedundant(treftl.toArrayReverse(), false); - if (treftypes.length != 1 || !glbType.members.isEmpty()) { - // step 4: replace all abstract types by their lower bounds. - boolean hasAbstract = false; - for (int i = 0; i < treftypes.length; i++) { - if (treftypes[i].unalias().symbol().kind == TYPE) - hasAbstract = true; - } - if (hasAbstract) { - treftl = Type.List.EMPTY; - for (int i = 0; i < treftypes.length; i++) { - if (treftypes[i].unalias().symbol().kind == TYPE) - treftl = new Type.List(treftypes[i].loBound(), treftl); - else - treftl = new Type.List(treftypes[i], treftl); - } - treftypes = elimRedundant(treftl.toArrayReverse(), false); - } - } - - if (treftypes.length != 1) { - // step 5: if there are conflicting instantiations of same - // class, replace them by lub/glb of arguments or lower bound. - Type lb = NoType; - for (int i = 0; - i < treftypes.length && - lb.symbol() != Global.instance.definitions.ALL_CLASS; - i++) { - for (int j = 0; j < i; j++) { - if (treftypes[j].symbol() == treftypes[i].symbol()) - lb = argGlb(treftypes[j], treftypes[i]); - } - } - if (lb != NoType) return lb; - } - - if (treftypes.length == 1 && glbType.members.isEmpty()) { - return treftypes[0]; - } else { - glbType.parts = treftypes; - return glbType; - } - } - - private static Type argGlb(Type tp1, Type tp2) { - switch (tp1) { - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - switch (tp2) { - case TypeRef(Type pre2, Symbol sym2, Type[] args2): - assert sym1 == sym2; - if (pre1.isSameAs(pre2)) { - Symbol[] tparams = sym1.typeParams(); - Type[] args = new Type[tparams.length]; - for (int i = 0; i < tparams.length; i++) { - if (args1[i].isSameAs(args2[i])) - args[i] = args1[i]; - else if ((tparams[i].flags & COVARIANT) != 0) - args[i]= lub(new Type[]{args1[i], args2[i]}); - else if ((tparams[i].flags & CONTRAVARIANT) != 0) - args[i]= glb(new Type[]{args1[i], args2[i]}); - else - return glb(new Type[]{tp1.loBound(), tp2.loBound()}); - } - return typeRef(pre1, sym1, args); - } - } - } - return glb(new Type[]{tp1.loBound(), tp2.loBound()}); - } - - /** Set scope `result' to glb of scopes `ss'. Return true iff succeeded. - */ - private static boolean setGlb(Scope result, Scope[] ss, Type glbThisType) { - for (int i = 0; i < ss.length; i++) - for (Scope.SymbolIterator it = ss[i].iterator(); it.hasNext(); ) - if (!addMember(result, it.next(), glbThisType)) return false; - return true; - } - - /** Add member `sym' to scope `s'. If`s' has already a member with same name, - * overwrite its info/low bound to form glb of both symbols. - */ - private static boolean addMember(Scope s, Symbol sym, Type glbThisType) { - Type syminfo = sym.info().substThis(sym.owner(), glbThisType); - Type symlb = sym.loBound().substThis(sym.owner(), glbThisType); - Type symvb = sym.vuBound().substThis(sym.owner(), glbThisType); - Scope.Entry e = s.lookupEntry(sym.name); - if (e == Scope.Entry.NONE) { - Symbol sym1 = sym.cloneSymbol(glbThisType.symbol()); - sym1.setInfo(syminfo); - if (sym1.kind == TYPE) { - sym1.setLoBound(symlb); - sym1.setVuBound(symvb); - } - s.enter(sym1); - } else { - Type einfo = e.sym.info(); - if (einfo.isSameAs(syminfo)) { - } else if (einfo.isSubType(syminfo) && sym.kind != ALIAS) { - } else if (syminfo.isSubType(einfo) && e.sym.kind != ALIAS) { - e.sym.setInfo(syminfo); - } else if (sym.kind == VAL && e.sym.kind == VAL || - sym.kind == TYPE && e.sym.kind == TYPE) { - e.sym.setInfo(glb(new Type[]{einfo, syminfo}).setOwner(e.sym)); - } else { - return false; - } - if (e.sym.kind == TYPE && sym.kind == TYPE) { - Type elb = e.sym.loBound(); - if (elb.isSameAs(symlb)) { - } else if (symlb.isSubType(elb)) { - } else if (elb.isSubType(symlb)) { - e.sym.setLoBound(symlb); - } else { - e.sym.setLoBound(lub(new Type[]{elb, symlb})); - } - Type evb = e.sym.vuBound(); - if (evb.isSameAs(symvb)) { - } else if (evb.isSubType(symvb)) { - } else if (symvb.isSubType(evb)) { - e.sym.setVuBound(symvb); - } else { - e.sym.setVuBound(glb(new Type[]{evb, symvb})); - } - } - } - return true; - } - - private static Type polyGlb(Type[] tps, Symbol[] tparams0) { - Type[][] hiboundss = new Type[tparams0.length][tps.length]; - Type[][] loboundss = new Type[tparams0.length][tps.length]; - Type[][] vuboundss = new Type[tparams0.length][tps.length]; - Type[] restps = new Type[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case PolyType(Symbol[] tparams, Type restp): - if (tparams.length == tparams0.length) { - for (int j = 0; j < tparams0.length; j++) { - hiboundss[j][i] = tparams[j].info() - .subst(tparams, tparams0); - loboundss[j][i] = tparams[j].loBound() - .subst(tparams, tparams0); - vuboundss[j][i] = tparams[j].vuBound() - .subst(tparams, tparams0); - } - restps[i] = restp.subst(tparams, tparams0); - } else { - return Type.NoType; - } - break; - default: - return Type.NoType; - } - } - Type[] hibounds = new Type[tparams0.length]; - Type[] lobounds = new Type[tparams0.length]; - Type[] vubounds = new Type[tparams0.length]; - for (int j = 0; j < tparams0.length; j++) { - hibounds[j] = lub(hiboundss[j]); - lobounds[j] = glb(loboundss[j]); - vubounds[j] = lub(vuboundss[j]); - } - Symbol[] tparams = new Symbol[tparams0.length]; - for (int j = 0; j < tparams.length; j++) { - tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE) - .setInfo(hibounds[j].subst(tparams0, tparams)) - .setLoBound(lobounds[j].subst(tparams0, tparams)) - .setVuBound(vubounds[j].subst(tparams0, tparams)); - } - return Type.PolyType(tparams, glb(restps).subst(tparams0, tparams)); - } - - private static Type methodGlb(Type[] tps, Symbol[] vparams0) { - Type[] restps = new Type[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case MethodType(Symbol[] vparams, Type restp): - if (vparams.length != vparams0.length) - return Type.NoType; - for (int j = 0; j < vparams.length; j++) - if (!vparams[i].type().isSameAs(vparams0[i].type()) || - (vparams[i].flags & (DEF | REPEATED)) != - (vparams0[i].flags & (DEF | REPEATED))) - return Type.NoType; - restps[i] = restp; - } - } - Symbol[] vparams = new Symbol[vparams0.length]; - for (int j = 0; j < vparams.length; j++) { - vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE); - } - return Type.MethodType(vparams, glb(restps)); - } - -// Erasure -------------------------------------------------------------------------- - - public static Map erasureMap = new MapOnlyTypes() { - public Type apply(Type t) { return t.erasure(); } - }; - - private static final Type[] unboxedType = - new Type[LastUnboxedTag + 1 - FirstUnboxedTag]; - private static final Name[] unboxedName = - new Name[LastUnboxedTag + 1 - FirstUnboxedTag]; - private static final Symbol[] boxedSymbol = - new Symbol[LastUnboxedTag + 1 - FirstUnboxedTag]; - - private static void mkStdClassType(int kind, String unboxedstr, Symbol boxedsym) { - unboxedType[kind - FirstUnboxedTag] = UnboxedType(kind); - unboxedName[kind - FirstUnboxedTag] = Name.fromString(unboxedstr); - boxedSymbol[kind - FirstUnboxedTag] = boxedsym; - } - - static void initializeUnboxedTypes(Definitions definitions) { - mkStdClassType(BYTE, "byte", definitions.BYTE_CLASS); - mkStdClassType(SHORT, "short", definitions.SHORT_CLASS); - mkStdClassType(CHAR, "char", definitions.CHAR_CLASS); - mkStdClassType(INT, "int", definitions.INT_CLASS); - mkStdClassType(LONG, "long", definitions.LONG_CLASS); - mkStdClassType(FLOAT, "float", definitions.FLOAT_CLASS); - mkStdClassType(DOUBLE, "double", definitions.DOUBLE_CLASS); - mkStdClassType(BOOLEAN, "boolean", definitions.BOOLEAN_CLASS); - mkStdClassType(UNIT, "void", definitions.UNIT_CLASS); - } - - /** Return unboxed type of given kind. - */ - public static Type unboxedType(int kind) { - return unboxedType[kind - FirstUnboxedTag]; - } - - /** Return the name of unboxed type of given kind. - */ - public static Name unboxedName(int kind) { - return unboxedName[kind - FirstUnboxedTag]; - } - - /** If type is boxed, return its unboxed equivalent; otherwise return the type - * itself. - */ - public Type unbox() { - switch (this) { - case TypeRef(_, Symbol clasz, Type[] args): - if (args.length == 0) { - for (int i = 0; i < boxedSymbol.length; i++) - if (boxedSymbol[i] == clasz) return unboxedType[i]; - } else if (args.length == 1) { - Definitions definitions = Global.instance.definitions; - if (clasz == definitions.ARRAY_CLASS) { - Type item = args[0]; - Type bound = item.upperBound(); - // todo: check with Philippe if this is what we want. - if (item.symbol().isClass() || - (bound.symbol() != definitions.ANY_CLASS && - bound.symbol() != definitions.ANYVAL_CLASS)) - { - return UnboxedArrayType(args[0].erasure()); - } - } - } - } - return this; - } - //where - private Type upperBound() { - switch (this) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == TYPE) - return pre.memberInfo(sym).upperBound(); - } - return this; - } - - /** Return the erasure of this type. - */ - public Type erasure() { - switch (this) { - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().erasure(); - case TypeRef(Type pre, Symbol sym, Type[] args): - switch (sym.kind) { - case ALIAS: case TYPE: - return sym.info().asSeenFrom(pre, sym.owner()).erasure(); - - case CLASS: - Definitions definitions = Global.instance.definitions; - if (sym == definitions.UNIT_CLASS) return this; - if (sym == definitions.OBJECT_CLASS || - sym == definitions.ALL_CLASS || - sym == definitions.ALLREF_CLASS) - return Type.typeRef(NoPrefix, definitions.ANY_CLASS, EMPTY_ARRAY); - else { - Type this1 = unbox(); - if (this1 != this) return this1; - else return Type.typeRef(NoPrefix, sym, EMPTY_ARRAY); - } - - default: throw new ApplicationError(sym + " has wrong kind: " + sym.kind); - } - case CompoundType(Type[] parents, _): - if (parents.length > 0) return parents[0].erasure(); - else return this; - case MethodType(Symbol[] params, Type tp): - Symbol[] params1 = erasureMap.map(params); - Type tp1 = tp.fullErasure(); - switch (tp1) { - case MethodType(Symbol[] params2, Type tp2): - Symbol[] newparams = new Symbol[params1.length + params2.length]; - System.arraycopy(params1, 0, newparams, 0, params1.length); - System.arraycopy(params2, 0, newparams, params1.length, params2.length); - return MethodType(newparams, tp2); - default: - if (params1 == params && tp1 == tp) return this; - else return MethodType(params1, tp1); - } - case PolyType(_, Type result): - return result.erasure(); - default: - return erasureMap.map(this); - } - } - - /** Return the full erasure of the type. Full erasure is the same - * as "normal" erasure, except that the "Unit" type is erased to - * the "void" type. - */ - public Type fullErasure() { - Type erasure = erasure(); - if (Global.instance.definitions.UNIT_CLASS == erasure.symbol()) - erasure = erasure.unbox(); - return erasure; - } - -// Object Interface ----------------------------------------------------------------- - - public String toString() { - return new SymbolTablePrinter().printType(this).toString(); - } - - public String toLongString() { - String str = toString(); - if (str.endsWith(".type")) return str + " (with underlying type " + widen() + ")"; - else return str; - } - - public int hashCode() { - switch (this) { - case ErrorType: - return ERRORtpe; - case NoType: - return NOtpe; - case NoPrefix: - return NOpre; - case ThisType(Symbol sym): - return THIStpe - ^ (sym.hashCode() * 41); - case TypeRef(Type pre, Symbol sym, Type[] args): - return TYPEREFtpe - ^ (pre.hashCode() * 41) - ^ (sym.hashCode() * (41*41)) - ^ (hashCode(args) * (41*41*41)); - case SingleType(Type pre, Symbol sym): - return SINGLEtpe - ^ (pre.hashCode() * 41) - ^ (sym.hashCode() * (41*41)); - case ConstantType(Type base, AConstant value): - return CONSTANTtpe - ^ (base.hashCode() * 41) - ^ (value.hashCode() * (41*41)); - case CompoundType(Type[] parts, Scope members): - return symbol().hashCode(); - //return COMPOUNDtpe - // ^ (hashCode(parts) * 41) - // ^ (members.hashCode() * (41 * 41)); - case MethodType(Symbol[] vparams, Type result): - int h = METHODtpe; - for (int i = 0; i < vparams.length; i++) - h = (h << 4) ^ (vparams[i].flags & SOURCEFLAGS); - return h - ^ (hashCode(Symbol.type(vparams)) * 41) - ^ (result.hashCode() * (41 * 41)); - case PolyType(Symbol[] tparams, Type result): - return POLYtpe - ^ (hashCode(tparams) * 41) - ^ (result.hashCode() * (41 * 41)); - case OverloadedType(Symbol[] alts, Type[] alttypes): - return OVERLOADEDtpe - ^ (hashCode(alts) * 41) - ^ (hashCode(alttypes) * (41 * 41)); - case UnboxedType(int kind): - return UNBOXEDtpe - ^ (kind * 41); - case UnboxedArrayType(Type elemtp): - return UNBOXEDARRAYtpe - ^ (elemtp.hashCode() * 41); - default: - throw new ApplicationError("bad type for hashCode: " + this); - } - } - - public static int hashCode(Object[] elems) { - int h = 0; - for (int i = 0; i < elems.length; i++) - h = h * 41 + elems[i].hashCode(); - return h; - } - - // todo: change in relation to needs. - - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof Type) { - Type that = (Type) other; - switch (this) { - case ErrorType: - return that == ErrorType; - case NoType: - return that == NoType; - case NoPrefix: - return that == NoPrefix; - case ThisType(Symbol sym): - switch (that) { - case ThisType(Symbol sym1): - return sym == sym1; - default: return false; - } - case TypeRef(Type pre, Symbol sym, Type[] args): - switch (that) { - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - return pre.equals(pre1) && sym == sym1 && equals(args, args1); - default: return false; - } - case SingleType(Type pre, Symbol sym): - switch (that) { - case SingleType(Type pre1, Symbol sym1): - return pre.equals(pre1) && sym == sym1; - default: return false; - } - case ConstantType(Type base, AConstant value): - switch (that) { - case ConstantType(Type base1, AConstant value1): - return base.equals(base1) && value.equals(value1); - default: return false; - } - case CompoundType(Type[] parts, Scope members): - switch (that) { - case CompoundType(Type[] parts1, Scope members1): - return this.symbol() == that.symbol(); - //return parts.equals(parts1) && members.equals(members1); - default: return false; - } - case MethodType(Symbol[] vparams, Type result): - switch (that) { - case MethodType(Symbol[] vparams1, Type result1): - if (vparams.length != vparams1.length) - return false; - for (int i = 0; i < vparams.length; i++) - if ((vparams[i].flags & SOURCEFLAGS) != - (vparams1[i].flags & SOURCEFLAGS)) - return false; - return - equals(Symbol.type(vparams), Symbol.type(vparams1)) && - result.equals(result1); - default: return false; - } - case PolyType(Symbol[] tparams, Type result): - switch (that) { - case PolyType(Symbol[] tparams1, Type result1): - return equals(tparams, tparams1) && result.equals(result1); - default: return false; - } - case OverloadedType(Symbol[] alts, Type[] alttypes): - switch (that) { - case OverloadedType(Symbol[] alts1, Type[] alttypes1): - return equals(alts, alts1) && equals(alttypes, alttypes1); - default: return false; - } - case UnboxedType(int kind): - switch (that) { - case UnboxedType(int kind1): - return kind == kind1; - default: return false; - } - case UnboxedArrayType(Type elemtp): - switch (that) { - case UnboxedArrayType(Type elemtp1): - return elemtp.equals(elemtp1); - default: return false; - } - default: - } - } - return false; - } - - public static boolean equals(Object[] elems1, Object[] elems2) { - if (elems1.length != elems2.length) return false; - for (int i = 0; i < elems1.length; i++) { - if (!elems1[i].equals(elems2[i])) return false; - } - return true; - } - -// Type.List class ----------------------------------------------------------------- - - /** A class for lists of types. - */ - public static class List { - public Type head; - public List tail; - public List(Type head, List tail) { - this.head = head; this.tail = tail; - } - public int length() { - return (this == EMPTY) ? 0 : 1 + tail.length(); - } - public Type[] toArray() { - Type[] ts = new Type[length()]; - copyToArray(ts, 0, 1); - return ts; - } - public void copyToArray(Type[] ts, int start, int delta) { - if (this != EMPTY) { - ts[start] = head; - tail.copyToArray(ts, start+delta, delta); - } - } - public Type[] toArrayReverse() { - Type[] ts = new Type[length()]; - copyToArray(ts, ts.length - 1, -1); - return ts; - } - - public String toString() { - if (this == EMPTY) return "List()"; - else return head + "::" + tail; - } - - public static List EMPTY = new List(null, null); - - public static List append(List l, Type tp) { - return (l == EMPTY) ? new List(tp, EMPTY) - : new List(l.head, append(l.tail, tp)); - } - } - -// Type.Constraint class ------------------------------------------------------- - - /** A class for keeping sub/supertype constraints and instantiations - * of type variables. - */ - public static class Constraint { - public List lobounds = List.EMPTY; - public List hibounds = List.EMPTY; - public Type inst = NoType; - - public boolean instantiate(Type tp) { - for (List l = lobounds; l != List.EMPTY; l = l.tail) { - if (!l.head.isSubType(tp)) return false; - } - for (List l = hibounds; l != List.EMPTY; l = l.tail) { - if (!tp.isSubType(l.head)) return false; - } - inst = tp; - return true; - } - } - -// Type.Error class -------------------------------------------------------------- - - /** A class for throwing type errors - */ - public static class Error extends java.lang.Error { - public String msg; - public Error(String msg) { - super(msg); - this.msg = msg; - } - } - - public static class Malformed extends Error { - public Malformed(Type pre, String tp) { - super("malformed type: " + pre + "#" + tp); - } - } - - /** A class for throwing type errors - */ - public static class VarianceError extends Error { - public VarianceError(String msg) { - super(msg); - } - } - - public static void explainTypes(Type found, Type required) { - if (Global.instance.explaintypes) { - boolean s = explainSwitch; - explainSwitch = true; - found.isSubType(required); - explainSwitch = s; - } - } -} - -/* A standard pattern match: - - case ErrorType: - case AnyType: - case NoType: - case ThisType(Symbol sym): - case TypeRef(Type pre, Symbol sym, Type[] args): - case SingleType(Type pre, Symbol sym): - case ConstantType(Type base, Object value): - case CompoundType(Type[] parts, Scope members): - case MethodType(Symbol[] vparams, Type result): - case PolyType(Symbol[] tparams, Type result): - case OverloadedType(Symbol[] alts, Type[] alttypes): -*/ - diff --git a/sources/scalac/symtab/TypeTags.java b/sources/scalac/symtab/TypeTags.java deleted file mode 100644 index 0a0d25cfb6..0000000000 --- a/sources/scalac/symtab/TypeTags.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - -public interface TypeTags { - - /** unboxed type tags - */ - int BYTE = 10; - int CHAR = 11; - int SHORT = 12; - int INT = 13; - int LONG = 14; - int FLOAT = 15; - int DOUBLE = 16; - int BOOLEAN = 17; - int UNIT = 18; - int STRING = 19; - - int FirstUnboxedTag = BYTE; - int LastUnboxedTag = UNIT; -} diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java deleted file mode 100644 index 7f04a3d147..0000000000 --- a/sources/scalac/symtab/classfile/AttributeParser.java +++ /dev/null @@ -1,216 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import scala.tools.util.AbstractFileReader; -import scalac.*; -import scalac.atree.AConstant; -import scalac.symtab.*; -import scalac.util.*; -import java.util.*; - -public class AttributeParser implements ClassfileConstants { - - /** the classfile input buffer - */ - protected AbstractFileReader in; - - /** the constant pool - */ - protected ConstantPool pool; - - protected ClassfileParser parser; - - /** constructor - */ - public AttributeParser(AbstractFileReader in, - ConstantPool pool, - ClassfileParser parser) - { - this.in = in; - this.pool = pool; - this.parser = parser; - } - - /** convert an attribute name into an attribute id - */ - public int nameToId(Name name) { - if (name == SOURCEFILE_N) - return SOURCEFILE_ATTR; - if (name == SYNTHETIC_N) - return SYNTHETIC_ATTR; - if (name == DEPRECATED_N) - return DEPRECATED_ATTR; - if (name == CODE_N) - return CODE_ATTR; - if (name == EXCEPTIONS_N) - return EXCEPTIONS_ATTR; - if (name == CONSTANT_VALUE_N) - return CONSTANT_VALUE_ATTR; - if (name == LINE_NUM_TABLE_N) - return LINE_NUM_TABLE_ATTR; - if (name == LOCAL_VAR_TABLE_N) - return LOCAL_VAR_TABLE_ATTR; - if (name == INNERCLASSES_N) - return INNERCLASSES_ATTR; - if (name == META_N) - return META_ATTR; - if (name == SCALA_N) - return SCALA_ATTR; - if (name == JACO_N) - return JACO_ATTR; - if (name == BRIDGE_N) - return BRIDGE_ATTR; - if (name == SIG_N) - return SIG_ATTR; - return BAD_ATTR; - } - - /** skip all attributes. - */ - public void skipAttributes() { - char nattr = in.nextChar(); - for (int i = 0; i < nattr; i++) { - in.skip(2); - in.skip(in.nextInt()); - } - } - - /** read all attributes associated with symbol 'sym' which are - * contained in 'attrs'. - */ - public Symbol readAttributes(Symbol def, Type type, int attrs) { - char nattr = in.nextChar(); - for (int i = 0; i < nattr; i++) { - Name attrName = pool.getName(in.nextChar()); - int attr = nameToId(attrName); - int attrLen = in.nextInt(); - if ((attrs & attr) == 0) { - //System.out.println("# skipping " + attrName + " of " + def); - in.skip(attrLen); - } else { - //System.out.println("# reading " + attrName + " of " + def); - readAttribute(def, type, attr, attrLen); - } - } - return def; - } - - /** read a single attribute 'attr' for symbol 'sym' with type 'type'. - */ - public void readAttribute(Symbol sym, Type type, int attr, int attrLen) { - switch (attr) { - // class attributes - case SCALA_ATTR: - try { - UnPickle.parse(parser.global, in.nextBytes(attrLen), sym); - return; - } catch (UnPickle.BadSignature exception) { - throw new RuntimeException(exception); - } - case INNERCLASSES_ATTR: - int n = in.nextChar(); - //System.out.println(sym + " has " + n + " innerclass entries"); - for (int i = 0; i < n; i++) { - int inner = in.nextChar(); - if (inner == 0) { in.skip(6); continue; } - int outer = in.nextChar(); - if (outer == 0) { in.skip(4); continue; } - int name = in.nextChar(); - if (name == 0) { in.skip(2); continue; } - int flags = in.nextChar(); - if ((flags & JAVA_ACC_STATIC) == 0) continue; - if ((flags & (JAVA_ACC_PUBLIC | JAVA_ACC_PROTECTED)) == 0) - continue; - if (pool.getClass(outer) != sym) continue; - Symbol alias = sym.linkedModule().moduleClass() - .newTypeAlias(Position.NOPOS, 0, - pool.getName(name).toTypeName(), - parser.make.classType(pool.getClass(inner))); - parser.statics.enterNoHide(alias); - } - //in.skip(attrLen); - return; - // method attributes - case CODE_ATTR: - in.skip(attrLen); - return; - case EXCEPTIONS_ATTR: - //int nexceptions = in.nextChar(); - //Type[] thrown = new Type[nexceptions]; - //for (int j = 0; j < nexceptions; j++) - // thrown[j] = make.classType(reader.readClassName(in.nextChar())); - //((MethodType)def.type).thrown = thrown; - in.skip(attrLen); - return; - case LINE_NUM_TABLE_ATTR: - in.skip(attrLen); - return; - case LOCAL_VAR_TABLE_ATTR: - in.skip(attrLen); - return; - // general attributes - case SYNTHETIC_ATTR: - sym.flags |= Modifiers.SYNTHETIC; - return; - case BRIDGE_ATTR: - sym.flags |= Modifiers.BRIDGE; - return; - case DEPRECATED_ATTR: - sym.flags |= Modifiers.DEPRECATED; - return; - case CONSTANT_VALUE_ATTR: - AConstant constant = pool.getConstantValue(in.nextChar()); - switch (constant) { - case INT(int value): - Definitions definitions = parser.global.definitions; - Symbol base = sym.getType().symbol(); - if (base == definitions.INT_CLASS) break; - if (base == definitions.CHAR_CLASS) - constant = AConstant.CHAR((char)value); - else if (base == definitions.SHORT_CLASS) - constant = AConstant.SHORT((short)value); - else if (base == definitions.BYTE_CLASS) - constant = AConstant.BYTE((byte)value); - else - constant = AConstant.BOOLEAN(value != 0); - } - sym.setInfo(parser.make.constantType(constant)); - return; - case META_ATTR: - //System.out.println("parsing meta data for " + sym); - String meta = pool.getString(in.nextChar()).trim(); - MetaParser mp = new MetaParser - (meta, tvars, sym, type, parser.c, parser.ctype, parser.make); - sym.setInfo(mp.parse()); - return; - case JACO_ATTR: - // this attribute is present in all PiCo generated classfiles - int mods = in.nextChar(); - mods |= (in.nextChar() << 16); - boolean algebraicClass = (mods & 0x00100000) != 0; - boolean caseClass = (mods & 0x00200000) != 0; - if (caseClass) - sym.flags |= Modifiers.CASE | Modifiers.JAVA; - in.skip(attrLen - 4); - return; - case SOURCEFILE_ATTR: - String name = pool.getString(in.nextChar()); - parser.c.getOrigin().setSourceFileAttribute(name); - parser.m.moduleClass().getOrigin().setSourceFileAttribute(name); - return; - default: - in.skip(attrLen); - return; - } - } - - Scope tvars = new Scope(); -} diff --git a/sources/scalac/symtab/classfile/CLRClassParser.java b/sources/scalac/symtab/classfile/CLRClassParser.java deleted file mode 100644 index 498237edbe..0000000000 --- a/sources/scalac/symtab/classfile/CLRClassParser.java +++ /dev/null @@ -1,538 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2003, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import scalac.Global; -import scalac.atree.AConstant; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; -import scalac.symtab.SymbolOrigin; -import scalac.symtab.Scope; -import scalac.symtab.Modifiers; -import scalac.symtab.Type.*; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -import scala.tools.util.Position; -import ch.epfl.lamp.compiler.msil.*; - -import java.util.Set; -import java.util.HashSet; -import java.util.Arrays; -import java.util.Iterator; - -public class CLRClassParser extends SymbolLoader { - - //########################################################################## - - private static Name[] ENUM_CMP_NAMES = new Name[] - { Names.EQ, Names.NE, Names.LT, Names.LE, Names.GT, Names.GE }; - - private static Name[] ENUM_BIT_LOG_NAMES = new Name[] - { Names.OR, Names.AND, Names.XOR }; - - private static JavaTypeFactory make; - - private static final CLRTypes clrTypes = CLRTypes.instance(); - - private final Type type; - - public CLRClassParser(Global global, Type type) { - super(global); - this.type = type; - } - - private Symbol clazz; - private Scope members; - private Symbol staticsClass; - private Scope statics; - scalac.symtab.Type clazzType; - - private final Scope tvars = new Scope(); - - protected String doComplete(Symbol root) { - clazz = root; - clazz.owner().initialize(); //??? - - if (make == null) - make = new JavaTypeCreator(global.definitions); - - clazz.flags = translateAttributes(type); - Type[] ifaces = type.getInterfaces(); - scalac.symtab.Type[] baseTypes = new scalac.symtab.Type[ifaces.length+1]; - baseTypes[0] = type.BaseType() != null ? getCLRType(type.BaseType()) - : (type.IsInterface() ? make.objectType() : make.anyType()); - for (int i = 0; i < ifaces.length; i++) - baseTypes[i + 1] = getCLRType(ifaces[i]); - members = new Scope(); - statics = new Scope(); - scalac.symtab.Type clazzInfo = - scalac.symtab.Type.compoundType(baseTypes, members, clazz); - clazz.setInfo(clazzInfo); - Symbol staticsModule = clazz.linkedModule(); - staticsClass = staticsModule.moduleClass(); - assert staticsClass.isModuleClass(): Debug.show(staticsClass); - scalac.symtab.Type staticsInfo = scalac.symtab.Type.compoundType - (scalac.symtab.Type.EMPTY_ARRAY, statics, staticsClass); - staticsClass.setInfo(staticsInfo); - staticsModule.setInfo(make.classType(staticsClass)); - clazzType = make.classType(clazz); - - // import nested types - Type[] nestedTypes = type.getNestedTypes(); - for (int i = 0; i < nestedTypes.length; i++) { - Type ntype = nestedTypes[i]; - if (ntype.IsNestedPrivate() || ntype.IsNestedAssembly() - || ntype.IsNestedFamANDAssem()) - continue; - Name classname = Name.fromString(ntype.Name).toTypeName(); - CLRClassParser loader = new CLRClassParser(global, ntype); - SymbolOrigin origin = SymbolOrigin.CLRAssembly(ntype.Assembly()); - Symbol nclazz = staticsClass.newLoadedClass - (JAVA, classname, loader, statics, origin); - clrTypes.map(nclazz, ntype); - } - - FieldInfo[] fields = type.getFields(); - for (int i = 0; i < fields.length; i++) { - if (fields[i].IsPrivate() || fields[i].IsAssembly() - || fields[i].IsFamilyAndAssembly()) - continue; - int mods = translateAttributes(fields[i]); - Name name = Name.fromString(fields[i].Name); - scalac.symtab.Type fieldType = getCLRType(fields[i].FieldType); - if (fields[i].IsLiteral() && !fields[i].FieldType.IsEnum()) - fieldType = make.constantType( - getConstant(fieldType.symbol(), fields[i].getValue())); - Symbol owner = fields[i].IsStatic() ? staticsClass : clazz; - Symbol field = owner.newField(Position.NOPOS, mods, name); - parseMeta(field, fields[i], fieldType); - (fields[i].IsStatic() ? statics : members).enterOrOverload(field); - clrTypes.map(field, fields[i]); - } - - Set methodsSet = new HashSet(Arrays.asList(type.getMethods())); - - PropertyInfo[] props = type.getProperties(); - for (int i = 0; i < props.length; i++) { - scalac.symtab.Type proptype = getCLSType(props[i].PropertyType); - if (proptype == null) - continue; - - MethodInfo getter = props[i].GetGetMethod(true); - MethodInfo setter = props[i].GetSetMethod(true); - if (getter == null || getter.IsPrivate() || - getter.IsAssembly() || getter.IsFamilyAndAssembly()) - continue; - assert props[i].PropertyType == getter.ReturnType; - Name n; - scalac.symtab.Type mtype; - - ParameterInfo[] gparams = getter.GetParameters(); - if (gparams.length == 0) { - n = Name.fromString(props[i].Name); - mtype = - scalac.symtab.Type.PolyType(Symbol.EMPTY_ARRAY, proptype); - } else { - n = Names.apply; - mtype = methodType(getter, getter.ReturnType); - } - int mods = translateAttributes(getter); - createMethod(n, mods, mtype, getter, getter.IsStatic()); - assert methodsSet.contains(getter) : "" + getter; - methodsSet.remove(getter); - - if (setter == null || setter.IsPrivate() || - setter.IsAssembly() || setter.IsFamilyAndAssembly()) - continue; - ParameterInfo[] sparams = setter.GetParameters(); - assert getter.IsStatic() == setter.IsStatic(); - assert setter.ReturnType == clrTypes.VOID; - assert sparams.length == gparams.length + 1 : "" + getter + "; " + setter; - - if (gparams.length == 0) - n = Name.fromString(n.toString() + Names._EQ); - else n = Names.update; - - mods = translateAttributes(setter); - mtype = methodType(setter, global.definitions.UNIT_TYPE()); - createMethod(n, mods, mtype, setter, setter.IsStatic()); - assert methodsSet.contains(setter) : "" + setter; - methodsSet.remove(setter); - } - - for (Iterator i = methodsSet.iterator(); i.hasNext(); ) { - MethodInfo method = (MethodInfo)i.next(); - if ((clrTypes.getSymbol(method) != null) || method.IsPrivate() - || method.IsAssembly() || method.IsFamilyAndAssembly()) - continue; - createMethod(method); - } - - // Create symbols related to delegate types - if(clrTypes.isDelegateType(type)) { - createDelegateView(); - createDelegateChainers(); - } - - // for enumerations introduce comparison and bitwise logical operations; - // the backend should recognize and replace them with comparison or - // bitwise logical operations on the primitive underlying type - if (type.IsEnum()) { - scalac.symtab.Type[] argTypes = new scalac.symtab.Type[] {clazzType}; - int mods = Modifiers.JAVA | Modifiers.FINAL; - for (int i = 0; i < ENUM_CMP_NAMES.length; i++) { - scalac.symtab.Type enumCmpType = - make.methodType(argTypes, - global.definitions.boolean_TYPE(), - scalac.symtab.Type.EMPTY_ARRAY); - createMethod(ENUM_CMP_NAMES[i], mods, enumCmpType, null, false); - } - for (int i = 0; i < ENUM_BIT_LOG_NAMES.length; i++) { - scalac.symtab.Type enumBitLogType = make.methodType - (argTypes, clazzType, scalac.symtab.Type.EMPTY_ARRAY); - createMethod - (ENUM_BIT_LOG_NAMES[i], mods, enumBitLogType, null, false); - } - } - - ConstructorInfo[] constrs = type.getConstructors(); - for (int i = 0; i < constrs.length; i++) { - if (constrs[i].IsStatic() || constrs[i].IsPrivate() - || constrs[i].IsAssembly() || constrs[i].IsFamilyAndAssembly()) - continue; - createConstructor(constrs[i]); - } - - Symbol constr = clazz.primaryConstructor(); - if (!constr.isInitialized()) { - constr.setInfo(scalac.symtab.Type.MethodType - (Symbol.EMPTY_ARRAY, clazzType)); - if ((clazz.flags & Modifiers.INTERFACE) == 0) - constr.flags |= Modifiers.PRIVATE; - } - - parseMeta(clazz, type, clazzInfo); - - return type + " from assembly " + type.Assembly(); - } - - private scalac.symtab.Type parseMeta(Symbol sym, - ICustomAttributeProvider member, - scalac.symtab.Type defaultType) - { - if (member !=null && member.IsDefined(clrTypes.PICO_META_ATTR, false)) { - Object[] attrs = - member.GetCustomAttributes(clrTypes.PICO_META_ATTR, false); - assert attrs.length == 1 : "attrs.length = " + attrs.length; - String meta = - (String)((Attribute)attrs[0]).getConstructorArguments()[0]; - defaultType = new MetaParser - (meta, tvars, sym, defaultType, clazz, clazzType, make).parse(); - } - sym.setInfo(defaultType); - return defaultType; - } - - private void createConstructor(ConstructorInfo constr) { - scalac.symtab.Type mtype = methodType(constr, clazzType); - if (mtype == null) - return; - Symbol constrSym = clazz.primaryConstructor(); - int mods = translateAttributes(constr); - if (constrSym.isInitialized()) { - constrSym = clazz.newConstructor(Position.NOPOS, mods); - clazz.addConstructor(constrSym); - } else { - constrSym.flags = mods; - } - setParamOwners(mtype, constrSym); - parseMeta(constrSym, constr, mtype); - clrTypes.map(constrSym, constr); - } - - private void createMethod(MethodInfo method) { - scalac.symtab.Type mtype = - methodType(method, method.ReturnType); - if (mtype == null) - return; - int mods = translateAttributes(method); - createMethod(getName(method), mods, mtype, method, method.IsStatic()); - } - - // Create static view methods within the delegate and the function type - // with the following signatures: - // def MyDelegate.view(MyDelegate): FunctionX[InvokeArgs..., InvokeRet]; - // def FunctionX.view(FunctionX[InvokeArgs..., InvokeRet]): MyDelegate; - private void createDelegateView() { - // Extract the parameter and return types of the Invoke method - MethodInfo invoke = (MethodInfo)type.GetMember("Invoke")[0]; - scalac.symtab.Type invokeRetType = getCLRType(invoke.ReturnType); - scalac.symtab.Type invokeParamTypes[] = - new scalac.symtab.Type[invoke.GetParameters().length]; - for(int j = 0; j < invoke.GetParameters().length; j++) - invokeParamTypes[j] = - getCLRType(invoke.GetParameters()[j].ParameterType); - scalac.symtab.Type funType = - global.definitions.FUNCTION_TYPE(invokeParamTypes, invokeRetType); - - // FORWARD MAPPING (Delegate => Function) - scalac.symtab.Type viewParamTypes[] = { getCLRType(type) }; - scalac.symtab.Type viewRetType = funType; - scalac.symtab.Type viewMethodType = make.methodType( - viewParamTypes, - viewRetType, - scalac.symtab.Type.EMPTY_ARRAY); - - createMethod(Names.view, Modifiers.JAVA, viewMethodType, null, true); - - // REVERSE MAPPING (Function => Delegate) - viewParamTypes = new scalac.symtab.Type[]{ funType }; - viewRetType = getCLRType(type); - viewMethodType = make.methodType( - viewParamTypes, - viewRetType, - scalac.symtab.Type.EMPTY_ARRAY); - - createMethod(Names.view, Modifiers.JAVA, viewMethodType, null, true); - } - - private void createDelegateChainers() { - int mods = Modifiers.JAVA | Modifiers.FINAL; - Type[] args = new Type[]{type}; - - createMethod(Names.PLUSEQ, mods, args, clrTypes.VOID, - clrTypes.DELEGATE_COMBINE, false); - createMethod(Names.MINUSEQ, mods, args, clrTypes.VOID, - clrTypes.DELEGATE_REMOVE, false); - createMethod - (Names.PLUS, mods, args, type, clrTypes.DELEGATE_COMBINE, false); - createMethod - (Names.MINUS, mods, args, type, clrTypes.DELEGATE_REMOVE, false); - } - - private Symbol createMethod(Name name, int mods, Type[] args, - Type retType, MethodInfo method, boolean statik) - { - return createMethod(name, mods, args, getCLSType(retType), method, statik); - } - private Symbol createMethod(Name name, int mods, Type[] args, - scalac.symtab.Type retType, - MethodInfo method, - boolean statik) - { - scalac.symtab.Type mtype = methodType(args, retType); - assert mtype != null : name; - return createMethod(name, mods, mtype, method, statik); - } - private Symbol createMethod(Name name, int mods, scalac.symtab.Type mtype, - MethodInfo method, boolean statik) - { - Symbol methodSym = (statik ? staticsClass: clazz) - .newMethod(Position.NOPOS, mods, name); - setParamOwners(mtype, methodSym); - parseMeta(methodSym, method, mtype); // sets the type to mtype if no meta - (statik ? statics : members).enterOrOverload(methodSym); - if (method != null) - clrTypes.map(methodSym, method); - return methodSym; - } - - private Name getName(MethodInfo method) { - final String name = method.Name; - if (method.IsStatic()) return Name.fromString(name); - final ParameterInfo[] params = method.GetParameters(); - if (name.equals("GetHashCode") && params.length == 0) - return Names.hashCode; - if (name.equals("ToString") && params.length == 0) - return Names.toString; - if (name.equals("Finalize") && params.length == 0) - return Names.finalize; - if (name.equals("Equals") && params.length == 1 - && params[0].ParameterType == clrTypes.OBJECT) - return Names.equals; - // TODO: check if the type implements ICloneable? - if (name.equals("Clone") && params.length == 0) - return Names.clone; - // Pretend that delegates have a 'apply' method instead of the 'Invoke' - // method. This is harmless because the latter one can't be called - // directly anyway. - if (name.equals("Invoke") - && clrTypes.isDelegateType(method.DeclaringType)) - return Names.apply; - return Name.fromString(name); - } - - //########################################################################## - - private Type[] getParamTypes(MethodBase method) { - ParameterInfo[] params = method.GetParameters(); - Type[] paramTypes = new Type[params.length]; - for (int i = 0; i < params.length; i++) - paramTypes[i] = params[i].ParameterType; - return paramTypes; - } - - private scalac.symtab.Type methodType(MethodBase method, Type rettype) { - scalac.symtab.Type rtype = getCLSType(rettype); - return rtype == null ? null : methodType(method, rtype); - } - - /** Return a method type for the given method. */ - private scalac.symtab.Type methodType(MethodBase method, - scalac.symtab.Type rettype) - { - return methodType(getParamTypes(method), rettype); - } - - /** Return a method type for the provided argument types and return type. */ - private scalac.symtab.Type methodType(Type[] argtypes, - scalac.symtab.Type rettype) - { - scalac.symtab.Type[] ptypes = new scalac.symtab.Type[argtypes.length]; - for (int i = 0; i < argtypes.length; i++) { - ptypes[i] = getCLSType(argtypes[i]); - if (ptypes[i] == null) - return null; - } - return make.methodType(ptypes, rettype, scalac.symtab.Type.EMPTY_ARRAY); - } - - private void setParamOwners(scalac.symtab.Type type, Symbol owner) { - switch (type) { - case PolyType(Symbol[] params, scalac.symtab.Type restype): - for (int i = 0; i < params.length; i++) params[i].setOwner(owner); - setParamOwners(restype, owner); - return; - case MethodType(Symbol[] params, scalac.symtab.Type restype): - for (int i = 0; i < params.length; i++) params[i].setOwner(owner); - setParamOwners(restype, owner); - return; - } - } - - //########################################################################## - - private scalac.symtab.Type getClassType(Type type) { - assert type != null; - scalac.symtab.Type res = - make.classType(type.FullName.replace('+', '.')); - if (res.isError()) - global.error("unknown class reference " + type.FullName); - return res; - } - - private scalac.symtab.Type getCLSType(Type type) { - if (/*type == clrTypes.BYTE ||*/ type == clrTypes.USHORT - || type == clrTypes.UINT || type == clrTypes.ULONG - || type.IsNotPublic() || type.IsNestedPrivate() - || type.IsNestedAssembly() || type.IsNestedFamANDAssem() - || type.IsPointer() - || (type.IsArray() && getCLSType(type.GetElementType()) == null)) - return null; - //Symbol s = clrTypes.getSymbol(type); - //scalac.symtab.Type t = s != null ? make.classType(s) : getCLRType(type); - return getCLRType(type); - } - - private scalac.symtab.Type getCLRType(Type type) { - if (type == clrTypes.OBJECT) - return make.objectType(); - if (type == clrTypes.STRING) - return make.stringType(); - if (type == clrTypes.VOID) - return make.voidType(); - if (type == clrTypes.BOOLEAN) - return make.booleanType(); - if (type == clrTypes.CHAR) - return make.charType(); - if (type == clrTypes.BYTE || type == clrTypes.UBYTE) - return make.byteType(); - if (type == clrTypes.SHORT || type == clrTypes.USHORT) - return make.shortType(); - if (type == clrTypes.INT || type == clrTypes.UINT) - return make.intType(); - if (type == clrTypes.LONG || type == clrTypes.ULONG) - return make.longType(); - if (type == clrTypes.FLOAT) - return make.floatType(); - if (type == clrTypes.DOUBLE) - return make.doubleType(); - if (type.IsArray()) - return make.arrayType(getCLRType(type.GetElementType())); - Symbol s = clrTypes.getSymbol(type); - return s != null ? make.classType(s) : getClassType(type); - } - - public AConstant getConstant(Symbol base, Object value) { - if (base == global.definitions.BOOLEAN_CLASS) - return AConstant.BOOLEAN(((Number)value).intValue() != 0); - if (base == global.definitions.BYTE_CLASS) - return AConstant.BYTE(((Number)value).byteValue()); - if (base == global.definitions.SHORT_CLASS) - return AConstant.SHORT(((Number)value).shortValue()); - if (base == global.definitions.CHAR_CLASS) - return AConstant.CHAR(((Character)value).charValue()); - if (base == global.definitions.INT_CLASS) - return AConstant.INT(((Number)value).intValue()); - if (base == global.definitions.LONG_CLASS) - return AConstant.LONG(((Number)value).longValue()); - if (base == global.definitions.FLOAT_CLASS) - return AConstant.FLOAT(((Number)value).floatValue()); - if (base == global.definitions.DOUBLE_CLASS) - return AConstant.DOUBLE(((Number)value).doubleValue()); - if (base == global.definitions.STRING_CLASS) - return AConstant.STRING((String)value); - throw Debug.abort("illegal value", Debug.show(value, base)); - } - - private static int translateAttributes(Type type) { - int mods = Modifiers.JAVA; - if (type.IsNotPublic() || type.IsNestedPrivate() - || type.IsNestedAssembly() || type.IsNestedFamANDAssem()) - mods |= Modifiers.PRIVATE; - else if (type.IsNestedFamily() || type.IsNestedFamORAssem()) - mods |= Modifiers.PROTECTED; - if (type.IsAbstract()) - mods |= Modifiers.ABSTRACT; - if (type.IsSealed()) - mods |= Modifiers.FINAL; - if (type.IsInterface()) - mods |= Modifiers.INTERFACE | Modifiers.TRAIT | Modifiers.ABSTRACT; - - return mods; - } - - private static int translateAttributes(FieldInfo field) { - int mods = Modifiers.JAVA; - if (field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly()) - mods |= Modifiers.PRIVATE; - else if (field.IsFamily() || field.IsFamilyOrAssembly()) - mods |= Modifiers.PROTECTED; - if (field.IsInitOnly()) - mods |= Modifiers.FINAL; - else - mods |= Modifiers.MUTABLE; - - return mods; - } - - private static int translateAttributes(MethodBase method) { - int mods = Modifiers.JAVA; - if (method.IsPrivate() || method.IsAssembly() || method.IsFamilyAndAssembly()) - mods |= Modifiers.PRIVATE; - else if (method.IsFamily() || method.IsFamilyOrAssembly()) - mods |= Modifiers.PROTECTED; - if (method.IsAbstract()) - mods |= Modifiers.DEFERRED; - - return mods; - } -} diff --git a/sources/scalac/symtab/classfile/CLRPackageParser.java b/sources/scalac/symtab/classfile/CLRPackageParser.java deleted file mode 100644 index c7e5296e17..0000000000 --- a/sources/scalac/symtab/classfile/CLRPackageParser.java +++ /dev/null @@ -1,151 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.util.Iterator; -import java.util.HashMap; -import java.util.HashSet; - -import scala.tools.util.AbstractFile; -import scala.tools.util.ByteArrayFile; -import scala.tools.util.VirtualDirectory; - -import scalac.Global; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; -import scalac.symtab.SymbolOrigin; - -import ch.epfl.lamp.compiler.msil.Type; -import ch.epfl.lamp.compiler.msil.Attribute; - -/** - * Package/namespace member loader for the CLR. - */ -public final class CLRPackageParser extends PackageParser { - - //######################################################################## - // Private Constants - - /** An empty directory */ - private static final AbstractFile EMPTY = new VirtualDirectory("<empty>"); - - //######################################################################## - // Protected Fields - - /** A table to collect types */ - protected final HashMap types = new HashMap(); - - //######################################################################## - // Public Constructors - - public CLRPackageParser(Global global, AbstractFile directory) { - super(global, directory); - } - - //######################################################################## - // Protected Methods - - protected PackageParser newPackageParser(AbstractFile directory) { - return new CLRPackageParser(global, directory); - } - - protected void collectAllMembers(Symbol clasz) { - super.collectAllMembers(clasz); - HashSet namespaces = new HashSet(); - CLRTypes.instance().collectMembers(clasz, types, namespaces); - for (Iterator i = namespaces.iterator(); i.hasNext(); ) { - String namespace = (String)i.next(); - if (!packages.containsKey(namespace)) - packages.put(namespace, EMPTY); - } - } - - protected void removeHiddenMembers(Symbol clasz) { - // Ignore all ".symbl" and ".class" files. - symbols.clear(); - classes.clear(); - super.removeHiddenMembers(clasz); - // Classes/Objects in the root package are hidden. - if (clasz.isRoot()) { types.clear(); } - // Source versions hide compiled versions except if separate - // compilation is enabled and the compiled version is more - // recent. In that case the compiled version hides the source - // version. - boolean separate = global.separate; - for (Iterator i = sources.entrySet().iterator(); i.hasNext(); ) { - if (types.isEmpty()) break; - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile sfile = (AbstractFile)entry.getValue(); - Type type = (Type)types.get(name); - boolean hidden = false; - if (type != null) - if (separate /* !!! && type.Assembly().getFile().lastModified() > sfile.lastModified() */) - hidden = true; - else - types.remove(name); - if (hidden) i.remove(); - } - // Packages are hidden by classes/objects with the same name. - packages.keySet().removeAll(types.keySet()); - } - - protected Scope createMemberSymbols(Symbol clasz) { - CLRTypes clrTypes = CLRTypes.instance(); - String namespace = clrTypes.getNameSpaceOf(clasz); - Scope members = super.createMemberSymbols(clasz); - - // import the CLR types contained in the package (namespace) - for (Iterator i = types.values().iterator(); i.hasNext(); ) { - Type type = (Type)i.next(); - - assert namespace.equals(type.Namespace) - : Debug.show(clasz, namespace) + " << " + type.FullName; - AbstractFile symfile = null; - if (type.IsDefined(clrTypes.SCALA_SYMTAB_ATTR, false)) { - Object[] attrs = type.GetCustomAttributes - (clrTypes.SCALA_SYMTAB_ATTR, false); - assert attrs.length == 1 : attrs.length; - Attribute a = (Attribute)attrs[0]; - assert a.GetType() == clrTypes.SCALA_SYMTAB_ATTR : a.toString(); - if (a.getConstructor() == clrTypes.SYMTAB_DEFAULT_CONSTR) - continue; - byte[] symtab = (byte[])a.getConstructorArguments()[0]; - symfile = new ByteArrayFile - (type.FullName, "[" + type.Assembly().GetName() + "]", - symtab); - } - SymbolLoader loader = symfile != null - ? new SymblParser(Global.instance, symfile) - : new CLRClassParser(Global.instance, type); - - Name classname = Name.fromString(type.Name).toTypeName(); - SymbolOrigin origin = SymbolOrigin.CLRAssembly(type.Assembly()); - Symbol clazz = clasz.newLoadedClass - (JAVA, classname, loader, members, origin); - clrTypes.map(clazz, type); - //Type moduleType = getType(type.FullName + "$"); - //map(clazz, moduleType != null ? moduleType : type); - } - - return members; - } - - protected String doComplete(Symbol root) { - String base = super.doComplete(root); - base = directory == EMPTY ? "" : base + " and "; - String namespace = CLRTypes.instance().getNameSpaceOf(root); - return base + "namespace '" + namespace + "'"; - } - - //######################################################################## -} // CLRPackageParser diff --git a/sources/scalac/symtab/classfile/CLRTypes.java b/sources/scalac/symtab/classfile/CLRTypes.java deleted file mode 100644 index f7a5af508c..0000000000 --- a/sources/scalac/symtab/classfile/CLRTypes.java +++ /dev/null @@ -1,330 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.util.List; -import java.util.LinkedList; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.LinkedHashSet; -import java.util.Arrays; -import java.util.Iterator; -import java.util.Comparator; - -import java.io.File; - -import scalac.Global; -import scalac.CompilerCommand; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; - -import ch.epfl.lamp.compiler.msil.*; - -/** - * Collects all types from all reference assemblies. - */ -public final class CLRTypes { - - //########################################################################## - - private static CLRTypes instance; - - /** Return the unique instance of the CLRTypes class */ - public static CLRTypes instance() { - assert instance != null; - return instance; - } - - /** Initialize the CLRTypes */ - public static void init(CompilerCommand args) { - instance = new CLRTypes(args); - } - - //########################################################################## - - public final Type BYTE; - public final Type UBYTE; - public final Type CHAR; - public final Type SHORT; - public final Type USHORT; - public final Type INT; - public final Type UINT; - public final Type LONG; - public final Type ULONG; - public final Type FLOAT; - public final Type DOUBLE; - public final Type BOOLEAN; - public final Type VOID; - public final Type ENUM; - public final Type DELEGATE; - - public final Type OBJECT; - public final Type STRING; - public final Type STRING_ARRAY; - - public final MethodInfo MEMBERWISE_CLONE; - - public final Type PICO_META_ATTR; - - public final Type SCALA_SYMTAB_ATTR; - public final ConstructorInfo SYMTAB_CONSTR; - public final ConstructorInfo SYMTAB_DEFAULT_CONSTR; - - public final MethodInfo DELEGATE_COMBINE; - public final MethodInfo DELEGATE_REMOVE; - - private final SymbolNameWriter snw = new SymbolNameWriter(); - - private Type[] types; - - private final CompilerCommand args; - - private CLRTypes(CompilerCommand args) { - this.args = args; - scala.tools.util.ClassPath.addFilesInPath( - assemrefs, args.assemrefs.value); - Assembly mscorlib = findAssembly("mscorlib.dll", true); - Type.initMSCORLIB(mscorlib); - findAllAssemblies(); - - if (getType("scala.Int") == null) { - findAssembly("scala.dll", true); - } - - BYTE = getType("System.SByte"); - UBYTE = getType("System.Byte"); - CHAR = getType("System.Char"); - SHORT = getType("System.Int16"); - USHORT = getType("System.UInt16"); - INT = getType("System.Int32"); - UINT = getType("System.UInt32"); - LONG = getType("System.Int64"); - ULONG = getType("System.UInt64"); - FLOAT = getType("System.Single"); - DOUBLE = getType("System.Double"); - BOOLEAN = getType("System.Boolean"); - VOID = getType("System.Void"); - ENUM = getType("System.Enum"); - DELEGATE = getType("System.MulticastDelegate"); - - OBJECT = getType("System.Object"); - STRING = getType("System.String"); - STRING_ARRAY = getType("System.String[]"); - - MEMBERWISE_CLONE = OBJECT.GetMethod("MemberwiseClone", Type.EmptyTypes); - - PICO_META_ATTR = Type.GetType("scala.runtime.MetaAttribute"); - SCALA_SYMTAB_ATTR = Type.GetType("scala.runtime.SymtabAttribute"); - final Type[] bytearray = new Type[]{ Type.GetType("System.Byte[]") }; - SYMTAB_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(bytearray); - SYMTAB_DEFAULT_CONSTR = - SCALA_SYMTAB_ATTR.GetConstructor(Type.EmptyTypes); - - Type delegate = Type.GetType("System.Delegate"); - Type[] dargs = new Type[]{delegate, delegate}; - DELEGATE_COMBINE = delegate.GetMethod("Combine", dargs); - DELEGATE_REMOVE = delegate.GetMethod("Remove", dargs); - - assert PICO_META_ATTR != null; - assert SCALA_SYMTAB_ATTR != null; - assert DELEGATE_COMBINE != null; - assert DELEGATE_REMOVE != null; - - Type[] types = Type.EmptyTypes; - Iterator as = assemblies.iterator(); - while (as.hasNext()) { - Type[] atypes = ((Assembly)as.next()).GetTypes(); - int j = 0; - for (int i = 0; i < atypes.length; i++) - // skip nested types - if (atypes[i].DeclaringType == null) - atypes[j++] = atypes[i]; - Type[] btypes = new Type[types.length + j]; - System.arraycopy(types, 0, btypes, 0, types.length); - System.arraycopy(atypes, 0, btypes, types.length, j); - types = btypes; - } - - Comparator typeNameComparator = - new Comparator() { - public int compare(Object o1, Object o2) { - Type t1 = (Type)o1; - Type t2 = (Type)o2; - return t1.FullName.compareTo(t2.FullName); - } - }; - - Arrays.sort(types, typeNameComparator); - this.types = types; - } - - //########################################################################## - // type mapping and lookup - - private final Map syms2members = new HashMap(); - private final Map members2syms = new HashMap(); - - public void map(Symbol sym, MemberInfo m) { - syms2members.put(sym, m); - members2syms.put(m, sym); - } - - public MemberInfo getMember(Symbol sym) { - return (MemberInfo)syms2members.get(sym); - } - - public Symbol getSymbol(MemberInfo m) { - return (Symbol)members2syms.get(m); - } - - public Type getType(String name) { - Type t = Type.GetType(name); - //assert t != null : name; - return t; - } - - public Type mkArrayType(Type elemType) { - return getType(elemType.FullName + "[]"); - } - - // Returns true if the given type is a delegate type. - public boolean isDelegateType(Type t) { - return t.BaseType() == DELEGATE; - } - - //########################################################################## - // assembly loading methods - - // a list of all loaded assemblies - private final List assemblies = new LinkedList(); - - // a set of all directories and assembly files - private final Set/*<File>*/ assemrefs = new LinkedHashSet(); - - /** Load the assembly with the given name - */ - private Assembly findAssembly(String name, boolean required) { - // see if the assembly is referenced directly - for (Iterator assems = assemrefs.iterator(); assems.hasNext();) { - File file = (File)assems.next(); - if (!file.getName().equals(name)) - continue; - Assembly assem = Assembly.LoadFrom(file.getPath()); - if (assem != null) { - assems.remove(); - assemblies.add(assem); - return assem; - } - } - // look in directories specified with the '-r' option - for (Iterator assems = assemrefs.iterator(); assems.hasNext();) { - File d = (File)assems.next(); - if (!d.isDirectory()) - continue; - File file = new File(d, name); - if (file.exists()) { - Assembly assem = Assembly.LoadFrom(file.getPath()); - if (assem != null) { - assemblies.add(assem); - return assem; - } - } - } - // try in the current directory - File file = new File(".", name); - if (file.exists()) { - Assembly assem = Assembly.LoadFrom(file.getPath()); - if (assem != null) { - assemblies.add(assem); - return assem; - } - } - - if (required) - abort(name); - - return null; - } - - /** Load the rest of the assemblies specified with the '-r' option - */ - private void findAllAssemblies() { - for (Iterator assems = assemrefs.iterator(); assems.hasNext();) { - File f = (File)assems.next(); - if (f.isFile()) { - Assembly assem = Assembly.LoadFrom(f.getPath()); - if (assem != null) { - assemblies.add(assem); - assems.remove(); - } - } - } - } - - private void abort(String name) { - //the Global instance is not yet constructed; use the Reporter from args - args.reporter().error(null, "cannot find assembly " + name + - "; use the -r option to specify its location"); - throw Debug.abort(); - } - - //########################################################################## - // collect the members contained in a given namespace - - /** Find the position of the first type whose name starts with - * the given prefix; return the length of the types array if no match - * is found so the result can be used to terminate loop conditions - */ - private int findFirst(String prefix) { - int m = 0, n = types.length - 1; - while (m < n) { - int l = (m + n) / 2; - int res = types[l].FullName.compareTo(prefix); - if (res < 0) m = l + 1; - else n = l; - } - return types[m].FullName.startsWith(prefix) ? m : types.length; - } - - /** Collects the members contained in the given Scala package (namespace) - */ - void collectMembers(Symbol pakage, Map/*<String,Type>*/ typesMap, - Set/*<String>*/ namespacesSet) - { - String namespace = pakage.isRoot() ? "" : snw.toString(pakage) + "."; - int nl = namespace.length(); - for (int i = findFirst(namespace); - i < types.length && types[i].FullName.startsWith(namespace); - i++) - { - Type type = types[i]; - if (type.FullName.equals("java.lang.Object") - || type.FullName.equals("java.lang.String")) { - continue; - } - int k = type.FullName.indexOf(".", nl); - if (k < 0) { - typesMap.put(type.Name, type); - } else { - namespacesSet.add(type.Namespace.substring(nl, k)); - } - } - } - - /** Returns the namespace of the given package */ - String getNameSpaceOf(Symbol pakage) { - assert pakage.hasPackageFlag() || pakage.isRoot(): Debug.show(pakage); - return pakage.isRoot() ? "" : snw.toString(pakage); - } - - //########################################################################## -} // CLRTypes diff --git a/sources/scalac/symtab/classfile/ClassParser.java b/sources/scalac/symtab/classfile/ClassParser.java deleted file mode 100644 index 5284d9cfed..0000000000 --- a/sources/scalac/symtab/classfile/ClassParser.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -import scalac.Global; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; -import scalac.util.Debug; - -/** This class implements a SymbolLoader that reads a class file. */ -public class ClassParser extends SymbolLoader { - - //######################################################################## - // Private Fields - - /** The class file to read */ - private final AbstractFile file; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with the specified class file. */ - public ClassParser(Global global, AbstractFile file) { - super(global); - this.file = file; - } - - //######################################################################## - // Protected Methods - - /** Completes the specified symbol by reading the class file. */ - protected String doComplete(Symbol root) throws IOException { - assert root.isClassType(): Debug.show(root); - ClassfileParser.parse(global, file, root); - return "class file '" + file + "'"; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/ClassfileConstants.java b/sources/scalac/symtab/classfile/ClassfileConstants.java deleted file mode 100644 index 02c07eea4b..0000000000 --- a/sources/scalac/symtab/classfile/ClassfileConstants.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scalac.util.Name; - -public interface ClassfileConstants { - - int JAVA_MAGIC = 0xCAFEBABE; - int JAVA_MAJOR_VERSION = 45; - int JAVA_MINOR_VERSION = 3; - - int JAVA_ACC_PUBLIC = 0x0001; - int JAVA_ACC_PRIVATE = 0x0002; - int JAVA_ACC_PROTECTED = 0x0004; - int JAVA_ACC_STATIC = 0x0008; - int JAVA_ACC_FINAL = 0x0010; - int JAVA_ACC_SUPER = 0x0020; - int JAVA_ACC_SYNCHRONIZED = 0x0020; - int JAVA_ACC_VOLATILE = 0x0040; - int JAVA_ACC_BRIDGE = 0x0040; - int JAVA_ACC_TRANSIENT = 0x0080; - int JAVA_ACC_NATIVE = 0x0100; - int JAVA_ACC_INTERFACE = 0x0200; - int JAVA_ACC_ABSTRACT = 0x0400; - int JAVA_ACC_STRICT = 0x0800; - int JAVA_ACC_SYNTHETIC = 0x1000; - - int CONSTANT_UTF8 = 1; - int CONSTANT_UNICODE = 2; - int CONSTANT_INTEGER = 3; - int CONSTANT_FLOAT = 4; - int CONSTANT_LONG = 5; - int CONSTANT_DOUBLE = 6; - int CONSTANT_CLASS = 7; - int CONSTANT_STRING = 8; - int CONSTANT_FIELDREF = 9; - int CONSTANT_METHODREF = 10; - int CONSTANT_INTFMETHODREF = 11; - int CONSTANT_NAMEANDTYPE = 12; - - int BAD_ATTR = 0x00000; - int SOURCEFILE_ATTR = 0x00001; - int SYNTHETIC_ATTR = 0x00002; - int DEPRECATED_ATTR = 0x00004; - int CODE_ATTR = 0x00008; - int EXCEPTIONS_ATTR = 0x00010; - int CONSTANT_VALUE_ATTR = 0x00020; - int LINE_NUM_TABLE_ATTR = 0x00040; - int LOCAL_VAR_TABLE_ATTR = 0x00080; - int INNERCLASSES_ATTR = 0x08000; - int META_ATTR = 0x10000; - int SCALA_ATTR = 0x20000; - int JACO_ATTR = 0x40000; - int BRIDGE_ATTR = 0x80000; - int SIG_ATTR = 0x100000; - - Name SOURCEFILE_N = Name.fromString("SourceFile"); - Name SYNTHETIC_N = Name.fromString("Synthetic"); - Name BRIDGE_N = Name.fromString("Bridge"); - Name DEPRECATED_N = Name.fromString("Deprecated"); - Name CODE_N = Name.fromString("Code"); - Name EXCEPTIONS_N = Name.fromString("Exceptions"); - Name CONSTANT_VALUE_N = Name.fromString("ConstantValue"); - Name LINE_NUM_TABLE_N = Name.fromString("LineNumberTable"); - Name LOCAL_VAR_TABLE_N = Name.fromString("LocalVariableTable"); - Name INNERCLASSES_N = Name.fromString("InnerClasses"); - Name META_N = Name.fromString("JacoMeta"); - Name SCALA_N = Name.fromString("ScalaSignature"); - Name JACO_N = Name.fromString("JacoInterface"); - Name SIG_N = Name.fromString("Signature"); - Name CONSTR_N = Name.fromString("<init>"); -} diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java deleted file mode 100644 index 235e350903..0000000000 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ /dev/null @@ -1,323 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scala.tools.util.AbstractFile; -import scala.tools.util.AbstractFileReader; -import scala.tools.util.Position; -import scalac.*; -import scalac.util.*; -import scalac.symtab.*; -import scalac.symtab.Scope.SymbolIterator; -import java.io.*; -import java.util.*; - -//todo: don't keep statics module in scope. - -public class ClassfileParser implements ClassfileConstants { - - static final int CLASS_ATTR = SOURCEFILE_ATTR - | INNERCLASSES_ATTR - | SYNTHETIC_ATTR - | DEPRECATED_ATTR - | META_ATTR - | SCALA_ATTR - | JACO_ATTR - | SIG_ATTR; - static final int METH_ATTR = CODE_ATTR - | EXCEPTIONS_ATTR - | SYNTHETIC_ATTR - | DEPRECATED_ATTR - | META_ATTR - | SIG_ATTR - | BRIDGE_ATTR; - static final int FIELD_ATTR = CONSTANT_VALUE_ATTR - | SYNTHETIC_ATTR - | DEPRECATED_ATTR - | META_ATTR - | SIG_ATTR; - - protected final Global global; - protected final AbstractFileReader in; - protected final Symbol c; - protected final Symbol m; - protected final Type ctype; - protected final JavaTypeFactory make; - protected final ConstantPool pool; - protected final AttributeParser attrib; - protected final Scope locals; - protected final Scope statics; - - - private ClassfileParser(Global global, AbstractFileReader in, Symbol c, JavaTypeFactory make, ConstantPool pool) { - this.global = global; - this.in = in; - this.c = c; - this.m = c.linkedModule(); - this.ctype = make.classType(c); - this.make = make; - this.pool = pool; - this.attrib = new AttributeParser(in, pool, this); - this.locals = new Scope(); - this.statics = new Scope(); - } - - - /** parse the classfile and throw IO exception if there is an - * error in the classfile structure - */ - public static void parse(Global global, AbstractFile file, Symbol c) throws IOException { - AbstractFileReader in = new AbstractFileReader(file); - try { - int magic = in.nextInt(); - if (magic != JAVA_MAGIC) - throw new IOException("class file '" + in.file + "' " - + "has wrong magic number 0x" + Integer.toHexString(magic) - + ", should be 0x" + Integer.toHexString(JAVA_MAGIC)); - int minorVersion = in.nextChar(); - int majorVersion = in.nextChar(); - if ((majorVersion < JAVA_MAJOR_VERSION) || - ((majorVersion == JAVA_MAJOR_VERSION) && - (minorVersion < JAVA_MINOR_VERSION))) - throw new IOException("class file '" + in.file + "' " - + "has unknown version " - + majorVersion + "." + minorVersion - + ", should be less than " - + JAVA_MAJOR_VERSION + "." + JAVA_MINOR_VERSION); - JavaTypeFactory make = new JavaTypeCreator(global.definitions); - Signatures sigs = new Signatures(global, make, in); - ConstantPool pool = new ConstantPool(in, sigs); - int flags = in.nextChar(); - Symbol clasz = pool.getClass(in.nextChar()); - if (c != clasz) - throw new IOException("class file '" + in.file + "' " - + "contains wrong class " + clasz.staticType()); - new ClassfileParser(global, in, c, make, pool).parse(flags); - } catch (RuntimeException e) { - if (global.debug) e.printStackTrace(); - throw new IOException("class file '" + in.file + "' is broken"); - } - } - - protected void parse(int flags) { - { - // todo: correct flag transition - c.flags = transFlags(flags); - if ((c.flags & Modifiers.DEFERRED) != 0) - c.flags = c.flags & ~Modifiers.DEFERRED | Modifiers.ABSTRACT; - Type supertpe = readClassType(in.nextChar()); - Type[] basetpes = new Type[in.nextChar() + 1]; - // set info of class - Type classInfo = Type.compoundType(basetpes, locals, c); - c.setInfo(classInfo); - // set info of statics class - Symbol staticsClass = m.moduleClass(); - assert staticsClass.isModuleClass(): Debug.show(staticsClass); - Type staticsInfo = Type.compoundType(Type.EMPTY_ARRAY, statics, staticsClass); - staticsClass.setInfo(staticsInfo); - m.setInfo(make.classType(staticsClass)); - basetpes[0] = supertpe; - for (int i = 1; i < basetpes.length; i++) - basetpes[i] = readClassType(in.nextChar()); - int fieldCount = in.nextChar(); - for (int i = 0; i < fieldCount; i++) - parseField(); - int methodCount = in.nextChar(); - for (int i = 0; i < methodCount; i++) - parseMethod(); - - Symbol constr = c.primaryConstructor(); - if (!constr.isInitialized()) { - constr.setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, ctype)); - if ((c.flags & Modifiers.INTERFACE) == 0) - constr.flags |= Modifiers.PRIVATE; - } - attrib.readAttributes(c, classInfo, CLASS_ATTR); - //System.out.println("dynamic class: " + c); - //System.out.println("statics class: " + staticsClass); - //System.out.println("module: " + m); - //System.out.println("modules class: " + m.type().symbol()); - - int savedFlags = c.flags; - c.flags |= Modifiers.INITIALIZED; - // hack to make memberType in addInheritedOverloaded work - if (global.currentPhase.id <= global.PHASE.REFCHECK.id() && - !c.name.toString().endsWith("$class")) - addInheritedOverloaded(); - - //if (global.debug) { - // Symbol[] elems = c.members().elements(); - // global.log(c + " defines: "); - // for (int i = 0; i < elems.length; i++) { - // global.log(elems[i] + ":" + elems[i].type()); - // } - //} - - c.flags = savedFlags; - - // Add static members of superclass - // todo: remove - Symbol superclass = supertpe.symbol(); - if (m.isJava() && superclass.isJava()) { - Symbol mclass = m.moduleClass(); - SymbolIterator i = superclass.linkedModule().moduleClass() - .members().iterator(); - outer: - while (i.hasNext()) { - Symbol member = i.next(); - Symbol current = statics.lookup(member.name); - if (!current.isNone()) { - if (!member.isTerm()) continue outer; - Type info = member.info(); - Symbol[] currents = current.alternativeSymbols(); - inner: - for (int j = 0; j < currents.length; j++) { - if (currents[j].owner() != mclass) - continue inner; - if (currents[j].info().isSubType(info)) - continue outer; - } - } - statics.enterOrOverload(member); - } - } - } - } - - private void addInheritedOverloaded() { - Symbol[] elems = c.members().elements(); - for (int i = 0; i < elems.length; i++) { - addInheritedOverloaded(elems[i]); - } - } - - private void addInheritedOverloaded(Symbol sym) { - if (sym.isMethod() && !sym.isConstructor()) { - sym.addInheritedOverloaded(sym.type()); - } - } - - /** convert Java modifiers into Scala flags - */ - public int transFlags(int flags) { - int res = 0; - if ((flags & JAVA_ACC_PRIVATE) != 0) - res |= Modifiers.PRIVATE; - else if ((flags & JAVA_ACC_PROTECTED) != 0) - res |= Modifiers.PROTECTED; - else if ((flags & JAVA_ACC_PUBLIC) == 0) - res |= Modifiers.PRIVATE; - if ((flags & JAVA_ACC_ABSTRACT) != 0) - res |= Modifiers.DEFERRED; - if ((flags & JAVA_ACC_FINAL) != 0) - res |= Modifiers.FINAL; - if ((flags & JAVA_ACC_INTERFACE) != 0) - res |= Modifiers.INTERFACE | Modifiers.TRAIT | Modifiers.ABSTRACT; - if ((flags & JAVA_ACC_SYNTHETIC) != 0) - res |= Modifiers.SYNTHETIC; - return res | Modifiers.JAVA; - } - - /** read a class name and return the corresponding class type - */ - protected Type readClassType(int i) { - return i == 0 ? make.anyType() : make.classType(pool.getClass(i)); - } - - /** read a field - */ - protected void parseField() { - int jflags = in.nextChar(); - int sflags = transFlags(jflags); - if ((jflags & JAVA_ACC_FINAL) == 0) sflags |= Modifiers.MUTABLE; - if ((sflags & Modifiers.PRIVATE) != 0) { - in.skip(4); - attrib.skipAttributes(); - } else { - Name name = pool.getName(in.nextChar()); - Symbol owner = getOwner(jflags); - Symbol symbol = owner.newTerm(Position.NOPOS, sflags, name); - Type type = pool.getFieldType(in.nextChar()); - symbol.setInfo(type); - attrib.readAttributes(symbol, type, FIELD_ATTR); - getScope(jflags).enterOrOverload(symbol); - } - } - - /** read a method - */ - protected void parseMethod() { - int jflags = in.nextChar(); - int sflags = transFlags(jflags); - if ((jflags & JAVA_ACC_BRIDGE) != 0) sflags |= Modifiers.PRIVATE; - if ((sflags & Modifiers.PRIVATE) != 0) { - in.skip(4); - attrib.skipAttributes(); - } else { - Name name = pool.getName(in.nextChar()); - Type type = pool.getMethodType(in.nextChar()); - Symbol owner = getOwner(jflags); - Symbol symbol; - boolean newConstructor = false; - if (name == CONSTR_N) { - switch (type) { - case MethodType(Symbol[] vparams, _): - type = Type.MethodType(vparams, ctype); - break; - default: - throw Debug.abort("illegal case", type); - } - symbol = owner.primaryConstructor(); - if (symbol.isInitialized()) { - symbol = owner.newConstructor(Position.NOPOS, sflags); - newConstructor = true; - } else { - symbol.flags = sflags; - } - } else { - symbol = owner.newTerm(Position.NOPOS, sflags, name); - } - setParamOwners(type, symbol); - symbol.setInfo(type); - attrib.readAttributes(symbol, type, METH_ATTR); - if (name != CONSTR_N) { - if ((symbol.flags & Modifiers.BRIDGE) == 0) - getScope(jflags).enterOrOverload(symbol); - } else if (newConstructor) - owner.addConstructor(symbol); - } - } - - /** return the owner of a member with given java flags - */ - private Symbol getOwner(int jflags) { - return (jflags & JAVA_ACC_STATIC) != 0 ? m.moduleClass() : c; - } - - /** return the scope of a member with given java flags - */ - private Scope getScope(int jflags) { - return (jflags & JAVA_ACC_STATIC) != 0 ? statics : locals; - } - - private void setParamOwners(Type type, Symbol owner) { - switch (type) { - case PolyType(Symbol[] params, Type result): - for (int i = 0; i < params.length; i++) - params[i].setOwner(owner); - setParamOwners(result, owner); - break; - case MethodType(Symbol[] params, Type result): - for (int i = 0; i < params.length; i++) params[i].setOwner(owner); - setParamOwners(result, owner); - break; - } - } -} diff --git a/sources/scalac/symtab/classfile/ConstantPool.java b/sources/scalac/symtab/classfile/ConstantPool.java deleted file mode 100644 index 0a042ae3f0..0000000000 --- a/sources/scalac/symtab/classfile/ConstantPool.java +++ /dev/null @@ -1,217 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import scalac.atree.AConstant; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scala.tools.util.AbstractFileReader; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.SourceRepresentation; - -/** This class implements the parsing of class file constant pools. */ -public class ConstantPool implements ClassfileConstants { - - //######################################################################## - // Private Fields - - /** The input file */ - private final AbstractFileReader in; - - /** The signature parser */ - private final Signatures parser; - - /** The start addresses of all constants */ - private final int[] starts; - - /** The values of the constants (or null if not yet read) */ - private final Object[] values; - - //######################################################################## - // Public Constructors - - /** Initializes this instance by reading constant pool in file. */ - public ConstantPool(AbstractFileReader in, Signatures parser) { - this.in = in; - this.parser = parser; - this.starts = new int[in.nextChar()]; - this.values = new Object[starts.length]; - for (int index = 1; index < starts.length; ) { - starts[index++] = in.bp; - switch (in.nextByte()) { - case CONSTANT_UTF8: - case CONSTANT_UNICODE: - in.skip(in.nextChar()); - continue; - case CONSTANT_CLASS: - case CONSTANT_STRING: - in.skip(2); - continue; - case CONSTANT_FIELDREF: - case CONSTANT_METHODREF: - case CONSTANT_INTFMETHODREF: - case CONSTANT_NAMEANDTYPE: - case CONSTANT_INTEGER: - case CONSTANT_FLOAT: - in.skip(4); - continue; - case CONSTANT_LONG: - case CONSTANT_DOUBLE: - in.skip(8); - index++; - continue; - default: - throw errorBadTag(in.bp - 1); - } - } - } - - //######################################################################## - // Public Methods - - /** Returns the string at given index. */ - public String getString(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof String) return (String)values[index]; - if (values[index] instanceof Name) return values[index].toString(); - String value = readString(starts[index]); - values[index] = value; - return value; - } - - /** Returns the name at given index. */ - public Name getName(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof Name) return (Name)values[index]; - Name value = readName(starts[index]); - values[index] = value; - return value; - } - - /** Returns the class at given index. */ - public Symbol getClass(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof Symbol) return (Symbol)values[index]; - Symbol value = readClass(starts[index]); - values[index] = value; - return value; - } - - /** Returns the field type at given index. */ - public Type getFieldType(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof Type) return (Type)values[index]; - Type value = readFieldType(starts[index]); - values[index] = value; - return value; - } - - /** Returns the method type at given index. */ - public Type getMethodType(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof Type) return clone((Type)values[index]); - Type value = readMethodType(starts[index]); - values[index] = value; - return value; - } - - /** Returns the constant value at given index. */ - public AConstant getConstantValue(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] != null) return (AConstant)values[index]; - AConstant value = readConstantValue(starts[index]); - values[index] = value; - return value; - } - - //######################################################################## - // Private Fields - - /** Reads the string at given address. */ - private String readString(int address) { - if (in.byteAt(address) != CONSTANT_UTF8) throw errorBadTag(address); - return parser.at(address).getSignature(); - } - - /** Reads the name at given address. */ - private Name readName(int address) { - return Name.fromString(readString(address)); - } - - /** Reads the class at given address. */ - private Symbol readClass(int address) { - if (in.byteAt(address) != CONSTANT_CLASS) throw errorBadTag(address); - int index = in.getChar(address + 1); - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - address = starts[index]; - if (in.byteAt(address) != CONSTANT_UTF8) throw errorBadTag(address); - return parser.at(address).readClassName(); - } - - /** Reads the field type at given address. */ - private Type readFieldType(int address) { - if (in.byteAt(address) != CONSTANT_UTF8) throw errorBadTag(address); - return parser.at(address).readValueType(); - } - - /** Reads the method type at given address. */ - private Type readMethodType(int address) { - if (in.byteAt(address) != CONSTANT_UTF8) throw errorBadTag(address); - return parser.at(address).readMethodType(); - } - - /** Reads the constant value at given address. */ - private AConstant readConstantValue(int address) { - switch (in.byteAt(address)) { - case CONSTANT_STRING: - return AConstant.STRING(getString(in.getChar(address + 1))); - case CONSTANT_INTEGER: - return AConstant.INT(in.getInt(address + 1)); - case CONSTANT_FLOAT: - return AConstant.FLOAT(in.getFloat(address + 1)); - case CONSTANT_LONG: - return AConstant.LONG(in.getLong(address + 1)); - case CONSTANT_DOUBLE: - return AConstant.DOUBLE(in.getDouble(address + 1)); - default: - throw errorBadTag(address); - } - } - - /** Returns the type with all its parameters symbols cloned. */ - private Type clone(Type type) { - switch (type) { - case MethodType(Symbol[] params, Type result): - Symbol[] clones = new Symbol[params.length]; - for (int i = 0; i < clones.length; i++) - clones[i] = params[i].cloneSymbol(Symbol.NONE); - return Type.MethodType(clones, result); - case ErrorType: - return type; - default: - throw Debug.abort("illegal case", type); - } - } - - /** Throws an exception signaling a bad constant index. */ - private RuntimeException errorBadIndex(int index) { - String error = "bad constant pool index: " + index; - throw new RuntimeException(error); - } - - /** Throws an exception signaling a bad tag at given address. */ - private RuntimeException errorBadTag(int address) { - int tag = in.byteAt(address); - String error = "bad constant pool tag " + tag + " at byte " + address; - throw new RuntimeException(error); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/JavaTypeCreator.java b/sources/scalac/symtab/classfile/JavaTypeCreator.java deleted file mode 100644 index d01f1923e2..0000000000 --- a/sources/scalac/symtab/classfile/JavaTypeCreator.java +++ /dev/null @@ -1,162 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import scalac.atree.AConstant; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.symtab.*; -import Type.*; - - -public class JavaTypeCreator implements JavaTypeFactory { - - protected final Definitions definitions; - - protected final Type ANY_TYPE; - protected final Type DOUBLE_TYPE; - protected final Type FLOAT_TYPE; - protected final Type LONG_TYPE; - protected final Type INT_TYPE; - protected final Type CHAR_TYPE; - protected final Type SHORT_TYPE; - protected final Type BYTE_TYPE; - protected final Type BOOLEAN_TYPE; - protected final Type UNIT_TYPE; - protected final Type OBJECT_TYPE; - protected final Type STRING_TYPE; - protected final Type ARRAY_TYPE; - - public JavaTypeCreator(Definitions definitions) { - this.definitions = definitions; - this.ANY_TYPE = classType(definitions.ANY_CLASS); - this.DOUBLE_TYPE = classType(definitions.DOUBLE_CLASS); - this.FLOAT_TYPE = classType(definitions.FLOAT_CLASS); - this.LONG_TYPE = classType(definitions.LONG_CLASS); - this.INT_TYPE = classType(definitions.INT_CLASS); - this.CHAR_TYPE = classType(definitions.CHAR_CLASS); - this.SHORT_TYPE = classType(definitions.SHORT_CLASS); - this.BYTE_TYPE = classType(definitions.BYTE_CLASS); - this.BOOLEAN_TYPE = classType(definitions.BOOLEAN_CLASS); - this.UNIT_TYPE = classType(definitions.UNIT_CLASS); - this.OBJECT_TYPE = classType(definitions.OBJECT_CLASS); - this.STRING_TYPE = classType(definitions.STRING_CLASS); - this.ARRAY_TYPE = classType(definitions.ARRAY_CLASS); - } - - public Type anyType() { - return ANY_TYPE; - } - - public Type byteType() { - return BYTE_TYPE; - } - - public Type shortType() { - return SHORT_TYPE; - } - - public Type charType() { - return CHAR_TYPE; - } - - public Type intType() { - return INT_TYPE; - } - - public Type longType() { - return LONG_TYPE; - } - - public Type floatType() { - return FLOAT_TYPE; - } - - public Type doubleType() { - return DOUBLE_TYPE; - } - - public Type booleanType() { - return BOOLEAN_TYPE; - } - - public Type voidType() { - return UNIT_TYPE; - } - - public Type objectType() { - return OBJECT_TYPE; - } - - public Type stringType() { - return STRING_TYPE; - } - - public Type classType(String classname) { - if (classname.equals("java.lang.Object")) - return objectType(); - if (classname.equals("java.lang.String")) - return stringType(); - return classType(definitions.getClass(classname)); - } - - public Type classType(Symbol clasz) { - return clasz.staticType(); - } - - public Type arrayType(Type elemtpe) { - return Type.appliedType(ARRAY_TYPE, new Type[]{elemtpe}); - } - - public Type methodType(Type[] argtpes, Type restpe, Type[] thrown) { - Symbol[] args = new Symbol[argtpes.length]; - for (int i = 0; i < args.length; i++) { - args[i] = Symbol.NONE.newTerm( // !!! should be newVParam - Position.NOPOS, Modifiers.PARAM, Name.fromString("x" + i)); - args[i].setInfo(objToAny(argtpes[i])); - } - return new MethodType(args, restpe); - } - private Type objToAny(Type tp) { - return tp.isSameAs(OBJECT_TYPE) ? ANY_TYPE : tp; - } - - public Type packageType(Name packagename) { - return null; - } - - /** return the constant type for the given constant. - */ - public Type constantType(AConstant value) { - return Type.constantType(value); - } - - /** return the type of a given constant. - */ - public Type typeOfValue(Object value) { - if (value instanceof Character) - return charType(); - else if (value instanceof Integer) - return intType(); - else if (value instanceof Long) - return longType(); - else if (value instanceof Float) - return floatType(); - else if (value instanceof Double) - return doubleType(); - else if (value instanceof String) - return stringType(); - else if (value instanceof Boolean) - return booleanType(); - else - throw Debug.abort("unknown constant type", value.getClass()); - } - -} diff --git a/sources/scalac/symtab/classfile/JavaTypeFactory.java b/sources/scalac/symtab/classfile/JavaTypeFactory.java deleted file mode 100644 index af89fce22b..0000000000 --- a/sources/scalac/symtab/classfile/JavaTypeFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scalac.atree.AConstant; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; - -public interface JavaTypeFactory { - Type anyType(); - Type byteType(); - Type shortType(); - Type charType(); - Type intType(); - Type longType(); - Type floatType(); - Type doubleType(); - Type booleanType(); - Type voidType(); - Type objectType(); - Type stringType(); - Type classType(String classname); - Type classType(Symbol clasz); - Type arrayType(Type elemtpe); - Type methodType(Type[] argtpes, Type restpe, Type[] thrown); - Type packageType(Name packagename); - Type constantType(AConstant value); -} diff --git a/sources/scalac/symtab/classfile/MetaParser.java b/sources/scalac/symtab/classfile/MetaParser.java deleted file mode 100644 index afc5f525e1..0000000000 --- a/sources/scalac/symtab/classfile/MetaParser.java +++ /dev/null @@ -1,287 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, 2003, 2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import scalac.util.Name; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.Scope; -import scalac.symtab.Type; -import scalac.ApplicationError; -import scalac.util.Debug; - -import java.util.Vector; -import java.util.StringTokenizer; -import java.util.NoSuchElementException; - -/** a parser class for parsing meta type information in classfiles - * generated by pico. - */ -class MetaParser { - private final Symbol owner; - private final StringTokenizer scanner; - private final Type defaultType; - private String token; - private final Scope tvars; - private Scope locals; - private final Symbol clazz; - private final Type ctype; - private final JavaTypeFactory make; - - MetaParser(String meta, Scope tvars, Symbol owner, Type defaultType, - Symbol clazz, Type ctype, JavaTypeFactory make) { - this.scanner = new StringTokenizer(meta, "()[], \t<;", true); - this.defaultType = defaultType; - this.owner = owner; - this.tvars = tvars; - this.clazz = clazz; - this.ctype = ctype; - this.make = make; - } - - private static Name getTypeName(String name) { - return Name.fromString(name).toTypeName(); - } - - private Symbol getTVar(String name) { - return getTVar(name, clazz.primaryConstructor()); - } - - private Symbol getTVar(String name, Symbol owner) { - if (name.startsWith("?")) { - Symbol s = (locals != null ? locals : tvars) - .lookup(getTypeName(name)); - if (s != Symbol.NONE) - return s; - else if (locals != null) { - s = tvars.lookup(getTypeName(name)); - if (s != Symbol.NONE) - return s; - } - s = owner.newTParam - (Position.NOPOS, 0, getTypeName(token), make.anyType()); - tvars.enter(s); - return s; - } else - return Symbol.NONE; - } - - private String nextToken() { - do { - token = scanner.nextToken().trim(); - } while (token.length() == 0); - return token; - } - - protected Type parse() { - if (scanner.hasMoreTokens()) { - nextToken(); - if (!scanner.hasMoreTokens()) - return defaultType; - if ("class".equals(token)) - return parseMetaClass(); - if ("method".equals(token)) - return parseMetaMethod(); - if ("field".equals(token)) - return parseMetaField(); - if ("constr".equals(token)) - return parseConstrField(); - } - return defaultType; - } - - protected Type parseMetaClass() { - nextToken(); - //System.out.println("parse meta class " + token);//DEBUG - if ("[".equals(token)) { - try { - Vector syms = new Vector(); - do { - nextToken(); - int vflag = 0; - if (token.equals("+")) { - nextToken(); - vflag = Modifiers.COVARIANT; - } else if (token.equals("-")) { - nextToken(); - vflag = Modifiers.CONTRAVARIANT; - } - assert token.startsWith("?"); - Symbol s = getTVar(token); - if (s == Symbol.NONE) - return defaultType; - s.flags |= vflag; - nextToken(); - //System.out.println("new var " + s + ", " + token);//DEBUG - if (token.equals("<")) { - nextToken(); - s.setInfo(parseType()); - } - syms.add(s); - } while (token.equals(",")); - assert "]".equals(token); - nextToken(); - Symbol[] smbls = (Symbol[])syms.toArray(new Symbol[syms.size()]); - //System.out.println("*** " + syms);//DEBUG - Type clazztype = Type.appliedType(ctype, Symbol.type(smbls)); - Symbol constr = clazz.primaryConstructor(); - switch (constr.rawInfo()) { - case MethodType(Symbol[] vparams, _): - constr.setInfo(Type.PolyType - (smbls, Type.MethodType(vparams, clazztype))); - break; - default: - throw new ApplicationError(constr.rawInfo()); - } - } catch (NoSuchElementException e) { - } - } - Type res = defaultType; - if ("extends".equals(token)) { - Vector basetpes = new Vector(); - do { - nextToken(); - basetpes.add(parseType()); - } while (token.equals("with")); - switch (defaultType) { - case CompoundType(_, Scope scope): - Type[] ts = (Type[])basetpes.toArray(new Type[basetpes.size()]); - res = Type.compoundType(ts, scope, defaultType.symbol()); - } - } - assert ";".equals(token); - return res; - } - - protected Type parseType() { - String name = token; - Symbol s = getTVar(name); - nextToken(); - if (s != Symbol.NONE) - return s.type(); - Type clazztype = make.classType(name).unalias(); - if (token.equals("[")) { - Vector types = new Vector(); - do { - nextToken(); - types.add(parseType()); - } while (token.equals(",")); - assert "]".equals(token); - nextToken(); - Type[] args = new Type[types.size()]; - types.toArray(args); - return Type.appliedType(clazztype, args); - } else { - return clazztype; - } - } - - protected Type parseMetaMethod() { - locals = new Scope(); - try { - nextToken(); - Symbol[] smbls = null; - //System.out.println("parse meta method " + token); - if ("[".equals(token)) { - Vector syms = new Vector(); - do { - nextToken(); - if ("]".equals(token)) - break; - assert token.startsWith("?"); - Symbol s = owner.newTParam - (Position.NOPOS, 0, getTypeName(token), make.anyType()); - locals.enter(s); - nextToken(); - if (token.equals("<")) { - nextToken(); - s.setInfo(parseType()); - } - syms.add(s); - } while (token.equals(",")); - assert "]".equals(token); - nextToken(); - smbls = (Symbol[])syms.toArray(new Symbol[syms.size()]); - } - if ("(".equals(token)) { - int i = 0; - Vector params = new Vector(); - do { - nextToken(); - if (")".equals(token)) - break; - int flags = 0; - if ("def".equals(token)) { - nextToken(); - flags |= Modifiers.DEF; - } - Symbol vp = owner.newVParam - (Position.NOPOS, flags, Name.fromString("x" + (i++))); - params.add(vp.setInfo(parseType())); - //System.out.println(" + " + token); - } while (token.equals(",")); - assert ")".equals(token); - nextToken(); - //System.out.println("+++ method " + token); - Type restpe = parseType(); - assert ";".equals(token); - Type mtype = Type.MethodType - ((Symbol[])params.toArray(new Symbol[params.size()]), - restpe); - return smbls == null ? mtype : Type.PolyType(smbls, mtype); - } else { - Type res = parseType(); - assert ";".equals(token); - return Type.PolyType - (smbls == null ? Symbol.EMPTY_ARRAY : smbls, res); - } - } catch (NoSuchElementException e) { - e.printStackTrace(); - return defaultType; - } finally { - locals = null; - } - } - - protected Type parseMetaField() { - nextToken(); - return parseType(); - } - - protected Type parseConstrField() { - try { - nextToken(); - //System.out.println("+++ constr " + token); - if ("(".equals(token)) { - int i = 0; - Vector params = new Vector(); - do { - nextToken(); - if (")".equals(token)) - break; - Symbol vp = owner.newVParam - (Position.NOPOS, 0, Name.fromString("x" + (i++))); - params.add(vp.setInfo(parseType())); - //System.out.println(" + " + token); - } while (token.equals(",")); - assert ")".equals(token); - nextToken(); - assert ";".equals(token); - return Type.MethodType((Symbol[])params.toArray(new Symbol[params.size()]), - ctype); - } else { - assert ";".equals(token); - return Type.PolyType(Symbol.EMPTY_ARRAY, ctype); - } - } catch (NoSuchElementException e) { - return defaultType; - } - } -} diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java deleted file mode 100644 index fdbc796916..0000000000 --- a/sources/scalac/symtab/classfile/PackageParser.java +++ /dev/null @@ -1,232 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.util.Iterator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map.Entry; - -import scala.tools.util.AbstractFile; - -import scalac.Global; -import scalac.symtab.Scope; -import scalac.symtab.SourceCompleter; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; -import scalac.symtab.SymbolOrigin; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Debug; - -/** - * This class implements a package member loader. It can be used to - * complete package class symbols. - */ -public class PackageParser extends SymbolLoader { - - //######################################################################## - // Protected Fields - - /** The directory to read */ - protected final AbstractFile directory; - - /** A table to collect .scala files */ - protected final HashMap/*<String,AbstractFile>*/ sources = new HashMap(); - /** A table to collect .symbl files */ - protected final HashMap/*<String,AbstractFile>*/ symbols = new HashMap(); - /** A table to collect .class files */ - protected final HashMap/*<String,AbstractFile>*/ classes = new HashMap(); - /** A table to collect subdirectories */ - protected final HashMap/*<String,AbstractFile>*/ packages = new HashMap(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public PackageParser(Global global, AbstractFile directory) { - super(global); - this.directory = directory; - assert directory != null; - } - - //######################################################################## - // Protected Methods - - /** Is the given name a valid input file base name? */ - protected boolean isValidName(String name) { - return name.length() > 0 - &&!name.endsWith("$class") - && name.indexOf("$$anon") == -1; - } - - /** Returns a new package parser for the given directory. */ - protected PackageParser newPackageParser(AbstractFile directory) { - return new PackageParser(global, directory); - } - - /** - * Collects all members of the package. This method is invoked by - * method "doComplete". It should not be invoked otherwise. - */ - protected void collectAllMembers(Symbol clasz) { - for (Iterator i = directory.list(); i.hasNext(); ) { - AbstractFile file = (AbstractFile)i.next(); - String filename = file.getName(); - if (file.isDirectory()) { - if (filename.equals("META-INF")) continue; - packages.put(filename, file); - continue; - } - if (filename.endsWith(".class")) { - String name = filename.substring(0, filename.length() - 6); - if (!isValidName(name)) continue; - if (!classes.containsKey(name)) classes.put(name, file); - continue; - } - if (filename.endsWith(".symbl")) { - String name = filename.substring(0, filename.length() - 6); - if (!isValidName(name)) continue; - if (!symbols.containsKey(name)) symbols.put(name, file); - continue; - } - if (filename.endsWith(".scala")) { - String name = filename.substring(0, filename.length() - 6); - if (!isValidName(name)) continue; - if (!sources.containsKey(name)) sources.put(name, file); - continue; - } - } - } - - /** - * Removes from the members collected by "collectAllMembers" all - * those that are hidden. This method is invoked by method - * "doComplete". It should not be invoked otherwise. - */ - protected void removeHiddenMembers(Symbol clasz) { - // Classes/Objects in the root package are hidden. - if (clasz.isRoot()) sources.clear(); - if (clasz.isRoot()) symbols.clear(); - if (clasz.isRoot()) classes.clear(); - // For all files "<N>.class" find the longest M such that - // there is a file "<M>.symbl" and M equals N or "<M>$" is a - // prefix of N. If the file "<N>.class" is less recent than - // the file "<M>.symbl" ignore the ".class" file. Otherwise, - // if M equals N, ignore the ".symbl" file. - for (Iterator i = classes.entrySet().iterator(); i.hasNext(); ) { - if (symbols.isEmpty()) break; - Entry entry = (Entry)i.next(); - String cname = (String)entry.getKey(); - AbstractFile cfile = (AbstractFile)entry.getValue(); - for (String zname = cname; true; ) { - AbstractFile zfile = (AbstractFile)symbols.get(zname); - if (zfile != null) { - if (cfile.lastModified() <= zfile.lastModified()) { - i.remove(); - } else if (zname == cname) { - symbols.remove(zname); - } - break; - } - int index = zname.lastIndexOf('$'); - if (index < 0) break; - zname = zname.substring(0, index); - } - } - // Source versions hide compiled versions except if separate - // compilation is enabled and the compiled version is more - // recent. In that case the compiled version hides the source - // version. - boolean separate = global.separate; - for (Iterator i = sources.entrySet().iterator(); i.hasNext(); ) { - if (symbols.isEmpty() && classes.isEmpty()) break; - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile sfile = (AbstractFile)entry.getValue(); - AbstractFile zfile = (AbstractFile)symbols.get(name); - AbstractFile cfile = (AbstractFile)classes.get(name); - boolean hidden = false; - if (zfile != null) - if (separate && zfile.lastModified() > sfile.lastModified()) - hidden = true; - else - symbols.remove(name); - if (cfile != null) - if (separate && cfile.lastModified() > sfile.lastModified()) - hidden = true; - else - classes.remove(name); - if (hidden) i.remove(); - } - // Packages are hidden by classes/objects with the same name. - packages.keySet().removeAll(sources.keySet()); - packages.keySet().removeAll(symbols.keySet()); - packages.keySet().removeAll(classes.keySet()); - } - - /** - * Creates symbols for all members left by method - * "removeHiddenMembers". This method is invoked by method - * "doComplete". It should not be invoked otherwise. - */ - protected Scope createMemberSymbols(Symbol clasz) { - Scope members = new Scope(); - for (Iterator i = sources.entrySet().iterator(); i.hasNext(); ) { - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile sfile = (AbstractFile)entry.getValue(); - Name classname = Name.fromString(name).toTypeName(); - SymbolLoader loader = new SourceCompleter(global, sfile); - SymbolOrigin origin = SymbolOrigin.ScalaFile(sfile); - clasz.newLoadedClass(0, classname, loader, members, origin); - } - for (Iterator i = symbols.entrySet().iterator(); i.hasNext(); ) { - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile zfile = (AbstractFile)entry.getValue(); - Name classname = Name.fromString(name).toTypeName(); - SymbolLoader loader = new SymblParser(global, zfile); - SymbolOrigin origin = SymbolOrigin.SymblFile(zfile); - clasz.newLoadedClass(0, classname, loader, members, origin); - } - for (Iterator i = classes.entrySet().iterator(); i.hasNext(); ) { - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile cfile = (AbstractFile)entry.getValue(); - Name classname = Name.fromString(name).toTypeName(); - SymbolLoader loader = new ClassParser(global, cfile); - SymbolOrigin origin = SymbolOrigin.ClassFile(cfile, null); - clasz.newLoadedClass(JAVA, classname, loader, members, origin); - } - for (Iterator i = packages.entrySet().iterator(); i.hasNext(); ) { - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile dfile = (AbstractFile)entry.getValue(); - Name packagename = Name.fromString(name); - SymbolLoader loader = newPackageParser(dfile); - SymbolOrigin origin = SymbolOrigin.Directory(dfile); - clasz.newLoadedPackage(packagename, loader, members, origin); - } - return members; - } - - /** Completes the package symbol by loading all its members. */ - protected String doComplete(Symbol root) { - assert root.isRoot() || root.isPackage(): Debug.show(root); - Symbol clasz = root.isRoot() ? root : root.moduleClass(); - collectAllMembers(clasz); - removeHiddenMembers(clasz); - Scope members = createMemberSymbols(clasz); - clasz.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, clasz)); - return "directory path '" + directory + "'"; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java deleted file mode 100644 index 22699b33a3..0000000000 --- a/sources/scalac/symtab/classfile/Pickle.java +++ /dev/null @@ -1,616 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import java.util.HashMap; -import java.io.*; -import scalac.Global; -import scalac.ApplicationError; -import scalac.atree.AConstant; -import scalac.util.*; -import scalac.symtab.*; -import Symbol.*; -import Type.*; - -public class Pickle implements Kinds, Modifiers, EntryTags { - - final static boolean debug = false; - -/*************************************************** - * Symbol table attribute format: see EntryTags.java - */ - public byte[] bytes; - private int bp; - - private Name rootname; - private Symbol rootowner; - private HashMap index; - private Object[] entries; - private int ep; - - /** Write symbol table info for root. - * root must be either a module or a class. - */ - public Pickle() { - index = new HashMap(); - entries = new Object[256]; - ep = 0; - } - - /** Pickle all symbols descending from `root'. - */ - public void add(Symbol root) { - if (!root.isExternal()) { - if (Global.instance.debug) System.out.println("pickling " + root); - if (index.get(root) == null) { - this.rootname = root.name.toTermName(); - this.rootowner = root.owner(); - putSymbol(root); - } - } - } - - /** Finalize pickler with given fullname. - */ - public void pickle() { - bytes = new byte[4096]; - bp = 0; - writeAttr(); - this.index = null; - this.entries = null; - } - - /** The number of elements defined in `bytes'. - */ - public int size() { - return bp; - } - - public void writeTo(File file) throws IOException { - OutputStream stream = new FileOutputStream(file); - stream.write(bytes, 0, size()); - stream.close(); - } - -/* ************************************************** - * Phase 1: Build entry table - ************************************************* */ - - /** Is root in symbol.owner*? - */ - private boolean isLocal(Symbol sym) { - return - sym.name.toTermName() == rootname && sym.owner() == rootowner - || - sym.isConstructor() && isLocal(sym.constructorClass()) - || - (sym.kind != NONE && isLocal(sym.owner())); - } - - /** Store entry `e' in index at next available position unless it it - * already there. Return true iff entry is new. - */ - private boolean putEntry(Object e) { - Integer n = (Integer) index.get(e); - if (n == null) { - //System.out.println("entry " + e);//DEBUG - if (ep == entries.length) { - Object[] entries1 = new Object[ep * 2]; - System.arraycopy(entries, 0, entries1, 0, ep); - entries = entries1; - } - entries[ep] = e; - index.put(e, new Integer(ep)); - ep++; - return true; - } else { - return false; - } - } - - /** Store symbol in index. If symbol is local, also store - * everything it refers to. - */ - private void putSymbol(Symbol sym) { - if (putEntry(sym)) { - if (debug) System.out.println("put " + sym); - if (isLocal(sym)) { - putEntry(sym.name); - putSymbol(sym.isConstructor() ? sym.constructorClass() : sym.owner()); - switch (sym.kind) { - case TYPE: - if (sym.isViewBounded()) putType(sym.vuBound()); - else putType(sym.info()); - putType(sym.loBound()); - break; - case ALIAS: - putType(sym.info()); - putSymbol(sym.allConstructors()); - break; - case CLASS: - putType(sym.info()); - if (sym.isModuleClass()) putSymbol(sym.sourceModule()); - putType(sym.typeOfThis()); - putSymbol(sym.allConstructors()); - Symbol[] elems = sym.members().elements(); - for (int i = 0; i < elems.length; i++) - putSymbol(elems[i]); - - break; - case VAL: - putType(sym.removeInheritedOverloaded(sym.info())); - if (sym.isConstructor() && - sym == sym.constructorClass().allConstructors()) - putSymbol(sym.constructorClass()); - else if (sym.isModule()) - putSymbol(sym.moduleClass()); - break; - default: - throw new ApplicationError(); - } - } else if (sym.kind != NONE) { - putEntry(sym.isModuleClass() || sym.isRoot() ? sym.name.toTermName() : sym.name); - if (!sym.owner().isRoot()) - putSymbol(sym.owner()); - } - } - } - - private void putSymbols(Symbol[] syms) { - for (int i = 0; i < syms.length; i++) - putSymbol(syms[i]); - } - - /** Store type and everythig it refers to in index. - */ - private void putType(Type tp) { - if (putEntry(tp)) { - switch (tp) { - case NoType: - break; - case NoPrefix: - putSymbol(Symbol.NONE); - // !!! code above is usefull for compatibility - // !!! nothing would be better line - break; - case ThisType(Symbol sym): - putSymbol(sym); - break; - case SingleType(Type pre, Symbol sym): - putType(pre); - putSymbol(sym); - break; - case ConstantType(Type base, AConstant value): - putType(base); - putConstant(value); - break; - case TypeRef(Type pre, Symbol sym, Type[] args): - putType(pre); - putSymbol(sym); - putTypes(args); - break; - case CompoundType(Type[] parents, Scope members): - Symbol clazz = tp.symbol(); - if (clazz.isCompoundSym()) putSymbol(clazz.owner()); - putSymbol(clazz); - putTypes(parents); - break; - case MethodType(Symbol[] vparams, Type result): - putType(result); - for (int i = 0; i < vparams.length; i++) { - Type ptype = vparams[i].type(); - putType(ptype); - int pflags = vparams[i].flags; - if ((pflags & (REPEATED | DEF)) != 0) - putEntry(new FlagsAndType(encodeFlags(pflags), ptype)); - } - break; - case PolyType(Symbol[] tparams, Type result): - putType(result); - putSymbols(tparams); - break; - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) alts[i].flags |= ALTERNATIVE; - putSymbols(alts); - putTypes(alttypes); - break; - default: - throw new ApplicationError(); - } - } - } - - private void putTypes(Type[] tps) { - for (int i = 0; i < tps.length; i++) - putType(tps[i]); - } - - private void putConstant(AConstant constant) { - if (putEntry(constant)) { - switch (constant) { - case STRING(String value): - putEntry(Name.fromString(value)); - return; - } - } - } - -/* ************************************************** - * Phase 2: Write byte array - ************************************************* */ - - private void resizeTo(int size) { - byte[] bytes1 = new byte[size]; - System.arraycopy(bytes, 0, bytes1, 0, bp); - bytes = bytes1; - } - - /** Write a byte of data - */ - private void writeByte(int b) { - if (bp == bytes.length) resizeTo(bytes.length * 2); - bytes[bp++] = (byte)b; - if (debug) System.out.print(b + " "); - } - - /** Write a natural number in big endian format, base 128. - * All but the last digits have bit 0x80 set. - */ - private void writeNat(int x) { - int y = x >>> 7; - if (y != 0) writeNatPrefix(y); - writeByte(x & 0x7f); - } - - private void writeNatPrefix(int x) { - int y = x >>> 7; - if (y != 0) writeNatPrefix(y); - writeByte((x & 0x7f) | 0x80); - } - - /** Write a natural number at `pos' - * If number is more than one byte, shift rest of array to make space. - */ - private void patchNat(int pos, int x) { - bytes[pos] = (byte) (x & 0x7f); - int y = x >>> 7; - if (y != 0) patchNatPrefix(pos, y); - } - - private void patchNatPrefix(int pos, int x) { - writeByte(0); - System.arraycopy(bytes, pos, bytes, pos+1, bp - (pos+1)); - bytes[pos] = (byte) ((x & 0x7f) | 0x80); - int y = x >>> 7; - if (y != 0) patchNatPrefix(pos, y); - } - - /** Write a long number in signed big endian format, base 256. - */ - private void writeLong(long x) { - long y = x >> 8; - long z = x & 0xff; - if (-y != z >> 7) writeLong(y); - writeByte((int) z); - } - - /** Write a reference to object, i.e., the object's number in the index. - */ - private void writeRef(Object ref) { - Integer i = (Integer) index.get(ref); - assert i != null : ref + " " + ref.getClass(); - writeNat(i.intValue()); - } - - private void writeRefs(Object[] es) { - for (int i = 0; i < es.length; i++) writeRef(es[i]); - } - - /** Write a name entry. Names are stored in Utf8 format. - */ - private void writeName(Name name) { - writeByte(name.isTermName() ? TERMname : TYPEname); - writeByte(0); // space for length - byte[] ascii = name.toAsciiUnsafe(); - while (bp + ascii.length > bytes.length) resizeTo(bytes.length * 2); - System.arraycopy(ascii, 0, bytes, bp, ascii.length); - if (debug) System.out.print(name); - bp = bp + ascii.length; - } - - /** Write a symbol entry. - */ - private void writeSymbol(Symbol sym) { - if (debug) System.out.println("write " + sym); - if (isLocal(sym)) { - switch (sym.kind) { - case TYPE: - writeByte(TYPEsym); - break; - case ALIAS: - writeByte(ALIASsym); - break; - case CLASS: - writeByte(CLASSsym); - break; - case VAL: - writeByte(VALsym); - break; - default: - throw new ApplicationError(); - } - writeByte(0); // space for length - writeRef(sym.name); - writeRef(sym.isConstructor() ? sym.constructorClass() : sym.owner()); - writeNat(sym.flags); - switch (sym.kind) { - case TYPE: - if (sym.isViewBounded()) writeRef(sym.vuBound()); - else writeRef(sym.info()); - writeRef(sym.loBound()); - break; - case ALIAS: - writeRef(sym.info()); - writeRef(sym.allConstructors()); - break; - case CLASS: - writeRef(sym.info()); - if (sym.isModuleClass()) writeRef(sym.sourceModule()); - writeRef(sym.typeOfThis()); - writeRef(sym.allConstructors()); - break; - case VAL: - writeRef(sym.removeInheritedOverloaded(sym.info())); - if (sym.isConstructor() && - sym == sym.constructorClass().allConstructors()) - writeRef(sym.constructorClass()); - else if (sym.isModule()) - writeRef(sym.moduleClass()); - break; - default: - throw new ApplicationError(); - } - } else if (sym.kind == NONE) { - writeByte(NONEsym); - writeByte(0); // space for length - } else { - if (sym.isModuleClass() || sym.isRoot()) { - writeByte(EXTMODCLASSref); - writeByte(0); // space for length - writeRef(sym.name.toTermName()); - } else { - writeByte(EXTref); - writeByte(0); // space for length - assert !sym.isConstructor() : sym; - writeRef(sym.name); - } - if (!sym.owner().isRoot()) - writeRef(sym.owner()); - } - sym.flags &= ~ALTERNATIVE; - } - - /** Write a type entry. - */ - private void writeType(Type tp) { - switch (tp) { - case NoType: - writeByte(NOtpe); - writeByte(0); // space for length - break; - case NoPrefix: - writeByte(THIStpe); - writeByte(0); // space for length - writeRef(Symbol.NONE); - // !!! code above is usefull for compatibility - // !!! following code would be better line: - // !!! writeByte(NOpre); - // !!! writeByte(0); // space for length - break; - case ThisType(Symbol sym): - writeByte(THIStpe); - writeByte(0); // space for length - writeRef(sym); - break; - - case SingleType(Type pre, Symbol sym): - writeByte(SINGLEtpe); - writeByte(0); // space for length - writeRef(pre); - writeRef(sym); - break; - - case ConstantType(Type base, AConstant value): - writeByte(CONSTANTtpe); - writeByte(0); // space for length - writeRef(base); - writeRef(value); - break; - - case TypeRef(Type pre, Symbol sym, Type[] args): - writeByte(TYPEREFtpe); - writeByte(0); // space for length - writeRef(pre); - writeRef(sym); - writeRefs(args); - break; - - case CompoundType(Type[] parents, Scope members): - writeByte(COMPOUNDtpe); - writeByte(0); // space for length - Symbol clazz = tp.symbol(); - writeByte(clazz.isCompoundSym() ? 1 : 0); - if (clazz.isCompoundSym()) writeRef(clazz.owner()); - writeRef(clazz); - writeRefs(parents); - break; - - case MethodType(Symbol[] vparams, Type result): - writeByte(METHODtpe); - writeByte(0); // space for length - writeRef(result); - for (int i = 0; i < vparams.length; i++) { - Type ptype = vparams[i].type(); - int pflags = vparams[i].flags; - if ((pflags & (REPEATED | DEF)) != 0) - writeRef(new FlagsAndType(encodeFlags(pflags), ptype)); - else - writeRef(ptype); - } - break; - - case PolyType(Symbol[] tparams, Type result): - writeByte(POLYtpe); - writeByte(0); // space for length - writeRef(result); - writeRefs(tparams); - break; - - case OverloadedType(Symbol[] alts, Type[] alttypes): - writeByte(OVERLOADEDtpe); - writeByte(0); // space for length - writeRefs(alts); - writeRefs(alttypes); - break; - - default: - throw new ApplicationError(); - } - } - - private void writeFlagsAndType(FlagsAndType ft) { - writeByte(FLAGGEDtpe); - writeByte(0); // space for length - writeNat(ft.flags); - writeRef(ft.type); - } - - /** Write a constant entry. - */ - private void writeConstant(AConstant constant) { - switch (constant) { - case UNIT: - writeByte(LITERALunit); - writeByte(0); // space for length - return; - case BOOLEAN(boolean value): - writeByte(LITERALboolean); - writeByte(0); // space for length - writeByte(value ? 1 : 0); - return; - case BYTE(byte value): - writeByte(LITERALbyte); - writeByte(0); // space for length - writeLong(value); - return; - case SHORT(short value): - writeByte(LITERALshort); - writeByte(0); // space for length - writeLong(value); - return; - case CHAR(char value): - writeByte(LITERALchar); - writeByte(0); // space for length - writeLong(value); - return; - case INT(int value): - writeByte(LITERALint); - writeByte(0); // space for length - writeLong(value); - return; - case LONG(long value): - writeByte(LITERALlong); - writeByte(0); // space for length - writeLong(value); - return; - case FLOAT(float value): - writeByte(LITERALfloat); - writeByte(0); // space for length - writeLong(Float.floatToIntBits(value)); - return; - case DOUBLE(double value): - writeByte(LITERALdouble); - writeByte(0); // space for length - writeLong(Double.doubleToLongBits(value)); - return; - case STRING(String value): - writeByte(LITERALstring); - writeByte(0); // space for length - writeRef(Name.fromString(value)); - return; - case NULL: - writeByte(LITERALnull); - writeByte(0); // space for length - return; - case ZERO: - writeByte(LITERALzero); - writeByte(0); // space for length - return; - default: - throw Debug.abort("unknown case", constant); - } - } - - private void writeEntry(Object e) { - int startpos = bp; - if (e instanceof Symbol) - writeSymbol((Symbol) e); - else if (e instanceof Type) - writeType((Type) e); - else if (e instanceof Name) - writeName((Name) e); - else if (e instanceof FlagsAndType) - writeFlagsAndType((FlagsAndType) e); - else if (e instanceof AConstant) - writeConstant((AConstant)e); - else - throw new ApplicationError(e); - patchNat(startpos + 1, bp - (startpos + 2)); - } - - private void writeAttr() { - writeNat(ep); - for (int i = 0; i < ep; i++) { - if (debug) System.out.print(i + "," + bp + ": "); - writeEntry(entries[i]); - if (debug) System.out.print("(" + entries[i] + ")"); - if (debug) System.out.println(); - } - } - - private static int encodeFlags(int flags) { - int n = 0; - if ((flags & REPEATED) != 0) n |= REPEATEDflag; - if ((flags & DEF) != 0) n |= DEFflag; - return n; - } - - static class FlagsAndType { - int flags; - Type type; - FlagsAndType(int flags, Type type) { - this.flags = flags; - this.type = type; - } - public boolean equals(Object other) { - if (other instanceof FlagsAndType) { - FlagsAndType that = (FlagsAndType) other; - return this.type.equals(that.type) && - this.flags == that.flags; - } else { - return false; - } - } - public int hashCode() { - return 37 + ((flags * 41) ^ type.hashCode()); - } - } -} - diff --git a/sources/scalac/symtab/classfile/Signatures.java b/sources/scalac/symtab/classfile/Signatures.java deleted file mode 100644 index 102bce1a64..0000000000 --- a/sources/scalac/symtab/classfile/Signatures.java +++ /dev/null @@ -1,175 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import scala.tools.util.AbstractFileReader; -import scalac.Global; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.SourceRepresentation; -import scalac.util.Debug; - -/** This class implements the parsing of class file signatures. */ -public class Signatures { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The Java type factory */ - private final JavaTypeFactory make; - - /** The input file */ - private final AbstractFileReader in; - - /** The address of the first byte of the current signature */ - private int first; - - /** The address of the last byte of the current signature */ - private int last; - - /** The current address (first <= current <= last) */ - private int current; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public Signatures(Global global, JavaTypeFactory make, - AbstractFileReader in) - { - this.global = global; - this.make = make; - this.in = in; - } - - //######################################################################## - // Public Methods - - /** - * Sets the address of the next signature to read. The address - * must point to the first byte of a CONSTANT_Utf8_info. - */ - public Signatures at(int address) { - first = address + 3; - last = first + in.getChar(address + 1) - 1; - current = first; - return this; - } - - /** Returns the current signature. */ - public String getSignature() { - return SourceRepresentation.ascii2string(in.buf, first, last-first+1); - } - - /** Reads the class signature at current address. */ - public Symbol readClassName() { - Symbol owner = global.definitions.ROOT_CLASS; - int start = current; - for (; current <= last; current++) { - int b = in.byteAt(current); - if (b == ';') break; - if (b != '/') continue; - Name name = Name.fromAscii(in.buf, start, current - start); - Symbol module = owner.members().lookup(name); - if (!module.isModule()) { - Symbol symbol = owner.newModule(Position.NOPOS, 0, name); - symbol.moduleClass().setInfo(Type.ErrorType); - error("could not find module " + symbol.staticType()); - if (module.isNone()) owner.members().enterNoHide(symbol); - module = symbol; - } - owner = module.moduleClass(); - start = current + 1; - } - - Symbol clasz = null; - Name name = Name.fromAscii(in.buf, start, current-start); - if (owner == global.definitions.JAVALANG.moduleClass()) { - if (name == Names.String) - clasz = global.definitions.STRING_CLASS; - else if (name == Names.Object) - clasz = global.definitions.OBJECT_CLASS; - } - if (clasz == null) { - name = name.toTypeName(); - clasz = owner.members().lookup(name); - } - - if (!clasz.isClass()) { - Symbol symbol = owner.newErrorClass(name); - error("could not find class " + symbol.staticType()); - if (clasz.isNone()) owner.members().enterNoHide(symbol); - clasz = symbol; - } - current++; - return clasz; - } - - /** Reads the value type signature at current address. */ - public Type readValueType() { - switch (in.byteAt(current++)) { - case 'V': return make.voidType(); - case 'Z': return make.booleanType(); - case 'B': return make.byteType(); - case 'S': return make.shortType(); - case 'C': return make.charType(); - case 'I': return make.intType(); - case 'J': return make.longType(); - case 'F': return make.floatType(); - case 'D': return make.doubleType(); - case 'L': return make.classType(readClassName()); - case '[': return make.arrayType(readValueType()); - default : return errorBadTypeTag(current - 1); - } - } - - /** Reads the method type signature at current address. */ - public Type readMethodType() { - if (in.byteAt(current++) != '(') return errorBadTypeTag(current - 1); - Type[] parameters = readParamterTypes(0); - Type result = readValueType(); - return make.methodType(parameters, result, Type.EMPTY_ARRAY); - } - - //######################################################################## - // Private Methods - - /** Reads the parameter types at current address. */ - private Type[] readParamterTypes(int i) { - if (in.byteAt(current) == ')') { - current++; - return new Type[i]; - } else { - Type type = readValueType(); - Type[] types = readParamterTypes(i + 1); - types[i] = type; - return types; - } - } - - /** Signals a bad tag at given address. Return ErrorType. */ - private Type errorBadTypeTag(int address) { - char tag = (char)in.byteAt(address); - error("bad tag '" + tag + "' in signature '" + getSignature() + "'"); - return Type.ErrorType; - } - - /** Signals the given error. */ - private void error(String error) { - global.error("class file '" + in.file + "': " + error); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/SymblParser.java b/sources/scalac/symtab/classfile/SymblParser.java deleted file mode 100644 index 5c948d9176..0000000000 --- a/sources/scalac/symtab/classfile/SymblParser.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -import scalac.Global; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; - -/** This class implements a SymbolLoader that reads a symbol file. */ -public class SymblParser extends SymbolLoader { - - //######################################################################## - // Private Fields - - /** The symbol file to read */ - private final AbstractFile file; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with the specified symbol file. */ - public SymblParser(Global global, AbstractFile file) { - super(global); - this.file = file; - } - - //######################################################################## - // Protected Methods - - /** Completes the specified symbol by reading the symbol file. */ - public String doComplete(Symbol root) throws IOException { - UnPickle.parse(global, file, root); - return "symbol file '" + file + "'"; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java deleted file mode 100644 index f3a715b480..0000000000 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ /dev/null @@ -1,643 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.util.HashMap; -import java.io.IOException; -import java.io.PrintStream; -import scala.tools.util.AbstractFile; -import scala.tools.util.Position; -import scalac.*; -import scalac.atree.AConstant; -import scalac.util.*; -import scalac.symtab.*; -import Symbol.*; -import Type.*; - -public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags { - -/*************************************************** - * Symbol table attribute format: see EntryTags.java - */ - static final boolean debug = true; - - public static void parse(Global global, AbstractFile file, Symbol root) - throws IOException - { - try { - parse(global, file.read(), root); - } catch (BadSignature exception) { - throw new IOException("symbol file '" + file.getPath() + "' " - + "could not be loaded; " + exception.getMessage()); - } - } - - /** - * The root symbol must be either a module or a non-module - * class. The unpickler initializes it. If it has a linked module - * or class, it will also be initialized. - */ - public static void parse(Global global, byte[] data, Symbol root) - throws BadSignature - { - new UnPickle(global, data, root); - } - - Symbol classroot; - Symbol moduleroot; - byte[] bytes; - int bp; - int[] index; - Object[] entries; - int paramFlags; - final Global global; - - private UnPickle(Global global, byte[] data, Symbol root) { - this.global = global; - this.classroot = root.isModule() ? root.linkedClass() : root; - this.moduleroot = root.isClassType() ? root.linkedModule() : root; - assert classroot == null || classroot.isClassType(): Debug.show(root); - assert moduleroot == null || moduleroot.isModule(): Debug.show(root); - if (root != moduleroot && moduleroot != null) { - moduleroot.moduleClass().setInfo(Type.NoType); - } - if (global.debug) global.log( - "unpickle " + root + " " + classroot + " " + moduleroot - + (moduleroot != null ? " " + moduleroot.moduleClass() : "")); - this.bytes = data; - this.bp = 0; - index = new int[readNat()]; - for (int i = 0; i < index.length; i++) { - index[i] = bp; - bp++; - bp = readNat() + bp; - } - entries = new Object[index.length]; - - if (global.debug) print(System.out); - - for (int i = 0; i < index.length; i++) { - if (isSymbolEntry(i)) getSymbol(i); - } - if (global.debug) global.log("unpickled " + root + ":" + root.rawInfo());//debug - if (!classroot.isInitialized() && !moduleroot.isInitialized()) - throw new BadSignature(this, "it does not define " + root); - // the isModule test is needed because moduleroot may become - // the case class factory method of classroot - if (moduleroot != null && moduleroot.isModule() && moduleroot.moduleClass().type() == Type.NoType) { - moduleroot.setInfo(Type.NoType); - } - } - - int readByte() { - return bytes[bp++]; - } - - int readNat() { - int b; - int x = 0; - do { - b = readByte(); - x = (x << 7) + (b & 0x7f); - } while ((b & 0x80) != 0); - return x; - } - - long readLong(int n) { - long x = 0; - for (int i = 0; i < n; i++) { - x = (x << 8) + (readByte() & 0xff); - } - int leading = 64 - (n * 8); - return x << leading >> leading; - } - - boolean isTypeEntry(int i) { - int tag = bytes[index[i]]; - return (firstTypeTag <= tag && tag <= lastTypeTag) || tag == NOpre; - } - - boolean isSymbolEntry(int i) { - int tag = bytes[index[i]]; - return (firstSymTag <= tag && tag <= lastSymTag); - } - - Name getName(int n) { - if (entries[n] == null) { - int savedBp = bp; - bp = index[n]; - int tag = bytes[bp++]; - int len = readNat(); - Name name = Name.fromAscii(bytes, bp, len); - switch (tag) { - case TERMname : entries[n] = name; break; - case TYPEname : entries[n] = name.toTypeName(); break; - default: throw new BadSignature(this); - } - bp = savedBp; - } - return (Name) entries[n]; - } - - Name readNameRef() { - return getName(readNat()); - } - - String decode(Name name) { - if (name.isTypeName()) return "type " + NameTransformer.decode(name); - else return "value " + NameTransformer.decode(name); - } - - /* - void enterSymbol(Symbol sym) { - Symbol owner = sym.owner(); - if (owner.kind == CLASS && - !sym.isConstructor() && !sym.isModuleClass()) { - Scope scope = owner.info().members(); - scope.enterOrOverload(sym); - } - } - */ - - void enterSymbol(Symbol sym) { - /* - if (global.debug) { - global.log("entering " + sym + ":" + sym.type() + " in " + sym.owner());//debug - if (sym.kind == CLASS) - global.log("primconstr = " + sym.primaryConstructor()); - } - */ - if ((sym.flags & ALTERNATIVE) != 0) { - sym.flags &= ~ALTERNATIVE; - } else { - Symbol owner = sym.owner(); - if (owner.kind == CLASS && - !sym.isConstructor() && !sym.isModuleClass()) { - Scope scope = owner.info().members(); - Symbol other = scope.lookup(sym.name); - if (other == Symbol.NONE) { - scope.enter(sym); - } else { - assert sym == other - : "double enter: " + other + ":" + other.rawFirstInfo() + "," + sym + ":" + sym.rawFirstInfo(); - } - } - } - } - - Symbol getSymbol(int n) { - if (entries[n] == null) { - int savedBp = bp; - bp = index[n]; - int tag = bytes[bp++]; - int end = readNat() + bp; - Symbol sym; - Symbol owner; - switch (tag) { - case NONEsym: - entries[n] = sym = Symbol.NONE; - break; - case EXTref: - case EXTMODCLASSref: - Name name = readNameRef(); - if (bp == end) { - owner = global.definitions.ROOT_CLASS; - } else { - assert bp < end; - owner = readSymbolRef(); - } - if (name == Names.ROOT && owner == Symbol.NONE) { - sym = global.definitions.ROOT_CLASS; - if (tag == EXTref) sym = sym; - // !!! line above is usefull for the transition - // !!! after some time, replace it by the following line: - // !!! assert tag != EXTref; - } else { - sym = owner.info().lookup(name); - if (tag == EXTMODCLASSref) { - /* - if (sym.kind == VAL) - switch (sym.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isModule()) sym = alts[i]; - } - */ - assert sym.isModule(); - sym = sym.moduleClass(); - } - } - entries[n] = sym; - if (sym.kind == NONE) { - if (global.debug) - global.log(owner.info().members().toString()); - throw new BadSignature(this, - "reference " + decode(name) + " of " + owner + - " refers to nonexisting symbol."); - } - break; - default: - assert isSymbolEntry(n) : n; - Name name = readNameRef(); - if (global.debug) - global.log("reading " + name + " at " + n); - owner = readSymbolRef(); - if (entries[n] == null) { - int flags = readNat(); - int inforef = readNat(); - switch (tag) { - case TYPEsym: - entries[n] = sym = owner.newAbstractType( - Position.NOPOS, flags, name); - if ((flags & VIEWBOUND) != 0) { - sym.setInfo(global.definitions.ANY_TYPE()); - sym.setVuBound(getType(inforef, sym)); - } else { - sym.setInfo(getType(inforef, sym)); - } - sym.setLoBound(readTypeRef(sym)); - break; - - case ALIASsym: - entries[n] = sym = owner.newTypeAlias( - Position.NOPOS, flags, name); - sym.setInfo(getType(inforef, sym)); - Symbol constr = readSymbolRef(); - break; - - case CLASSsym: - if ((flags & MODUL) != 0) { - Symbol modulesym = readSymbolRef(); - entries[n] = sym = modulesym.moduleClass(); - sym.flags = flags; - } else if (classroot != null && name == classroot.name && owner == classroot.owner()) { - if (global.debug) - global.log("overwriting " + classroot); - entries[n] = sym = classroot; - sym.flags = flags; - } else { - entries[n] = sym = owner.newClass( - Position.NOPOS, flags, name); - } - sym.setInfo(getType(inforef, sym)); - sym.setTypeOfThis(readTypeRef(sym)); - Symbol constr = readSymbolRef(); - assert constr == sym.allConstructors(); - break; - - case VALsym: - if (moduleroot != null && name == moduleroot.name && owner == moduleroot.owner()) { - if (global.debug) - global.log("overwriting " + moduleroot); - entries[n] = sym = moduleroot; - sym.flags = flags; - } else if ((flags & MODUL) != 0) { - entries[n] = sym = owner.newModule( - Position.NOPOS, flags, name); - } else if (name == Names.CONSTRUCTOR) { - Symbol tsym = bp < end ? readSymbolRef() : null; - if (tsym == null) { - entries[n] = sym = owner.newConstructor( - Position.NOPOS, flags); - } else { - entries[n] = sym = tsym.allConstructors(); - sym.flags = flags; - } - } else { - entries[n] = sym = owner.newTerm( - Position.NOPOS, flags, name); - } - if (sym.isModule()) { - Symbol clasz = readSymbolRef(); - assert clasz == sym.moduleClass(): Debug.show(sym); - } - Type owntype = getType(inforef, sym); - sym.setInfo(owntype); - break; - - default: - throw new BadSignature(this); - } - - enterSymbol(sym); - } - } - bp = savedBp; - } - return (Symbol) entries[n]; - } - - Symbol readSymbolRef() { - return getSymbol(readNat()); - } - - Symbol[] readSymbolRefs(int end) { - return readSymbolRefs(0, end); - } - - Symbol[] readSymbolRefs(int nread, int end) { - if (bp == end) { - return new Symbol[nread]; - } else { - assert bp < end; - int bp0 = bp; - int ref = readNat(); - if (isSymbolEntry(ref)) { - Symbol s = getSymbol(ref); - Symbol[] ss = readSymbolRefs(nread+1, end); - ss[nread] = s; - return ss; - } else { - bp = bp0; - return new Symbol[nread]; - } - } - } - - Type getType(int n, Symbol owner) { - Type tpe = (Type)entries[n]; - if (tpe == null) { - int savedBp = bp; - bp = index[n]; - int tag = bytes[bp++]; - int end = readNat() + bp; - switch (tag) { - case NOtpe: - tpe = Type.NoType; - break; - case NOpre: - tpe = Type.NoPrefix; - break; - case THIStpe: - Symbol sym = readSymbolRef(); - tpe = (sym.kind == NONE) ? Type.NoPrefix : Type.ThisType(sym); - // !!! code above is usefull for the transition - // !!! after some time, replace it by the following line: - // !!! tpe = Type.ThisType(readSymbolRef()); - break; - case SINGLEtpe: - Type prefix = readTypeRef(owner); - Symbol symbol = readSymbolRef(); - tpe = symbol.isRoot() ? symbol.thisType() : Type.singleType(prefix, symbol); - // !!! code above is usefull for the transition - // !!! after some time, replace it by the following line: - // !!! tpe = Type.singleType(readTypeRef(), readSymbolRef()); - break; - case CONSTANTtpe: - Type base = readTypeRef(owner); - AConstant value = readConstantRef(); - tpe = new Type.ConstantType(base, value); - break; - case TYPEREFtpe: - tpe = Type.newTypeRefUnsafe( // !!! - readTypeRef(owner), readSymbolRef(), readTypeRefs(end, owner)); - break; - case COMPOUNDtpe: - boolean isCompoundSym = readByte() != 0; - Symbol ctOwner = isCompoundSym - ? readSymbolRef() - : null; - int ctClassRef = readNat(); - Symbol ctClass = isCompoundSym - ? (Symbol)entries[ctClassRef] - : getSymbol(ctClassRef); - Type[] parents = readTypeRefs(end, owner); - if (ctClass == null) { - tpe = Type.compoundTypeWithOwner(ctOwner, parents, new Scope()); - entries[ctClassRef] = tpe.symbol(); - } else { - tpe = Type.compoundType(parents, new Scope(), ctClass); - } - break; - case METHODtpe: - Type restype = readTypeRef(owner); - int bp1 = bp; - Type[] argtypes = readTypeRefs(end, owner); - int[] flags = new int[argtypes.length]; - bp = bp1; - readFlags(flags); - Symbol[] params = new Symbol[argtypes.length]; - for (int i = 0; i < argtypes.length; i++) { - Name name = Name.fromString("$" + i); - params[i] = owner.newVParam( - Position.NOPOS, flags[i], name, argtypes[i]); - } - tpe = Type.MethodType(params, restype); - break; - case POLYtpe: - Type restype = readTypeRef(owner); - tpe = Type.PolyType(readSymbolRefs(end), restype); - break; - case OVERLOADEDtpe: - int bp0 = bp; - Symbol[] alts = readSymbolRefs(end); - int bp1 = bp; - Type[] alttypes = readTypeRefs(end, alts); - assert alts.length == alttypes.length - : alts.length + "!=" + alttypes.length + - " at " + bp0 + "/" + bp1 + "/" + bp; - tpe = Type.OverloadedType(alts, alttypes); - break; - case FLAGGEDtpe: - readNat(); // skip flags - tpe = readTypeRef(owner); - break; - default: - throw new BadSignature(this); - } - if (tag != METHODtpe) entries[n] = tpe; - bp = savedBp; - } - return tpe; - } - - Type readTypeRef(Symbol owner) { - return getType(readNat(), owner); - } - - Type[] readTypeRefs(int end, Symbol owner) { - return readTypeRefs(0, end, owner, null); - } - - Type[] readTypeRefs(int end, Symbol[] owners) { - return readTypeRefs(0, end, null, owners); - } - - Type[] readTypeRefs(int nread, int end, Symbol owner, Symbol[] owners) { - assert (owner != null) ^ (owners != null); - if (bp == end) { - return new Type[nread]; - } else { - assert bp < end : bp + ">" + end; - int bp0 = bp; - int ref = readNat(); - if (isTypeEntry(ref)) { - Type t = getType(ref, owner != null ? owner : owners[nread]); - Type[] ts = readTypeRefs(nread + 1, end, owner, owners); - ts[nread] = t; - return ts; - } else { - bp = bp0; - return new Type[nread]; - } - } - } - - void readFlags(int[] flags) { - for (int i = 0; i < flags.length; i++) - flags[i] = getFlags(readNat()); - } - - int getFlags(int n) { - int savedBp = bp; - bp = index[n]; - int tag = bytes[bp++]; - int end = readNat() + bp; - int flags = (tag == FLAGGEDtpe) ? decodeFlags(readNat()) : 0; - bp = savedBp; - return flags; - } - - private static int decodeFlags(int n) { - int flags = 0; - if ((n & REPEATEDflag) != 0) flags |= REPEATED; - if ((n & DEFflag) != 0) flags |= DEF; - return flags; - } - - AConstant readConstant() { - int tag = bytes[bp++]; - int len = readNat(); - switch (tag) { - case LITERALunit: - return AConstant.UNIT; - case LITERALboolean: - return AConstant.BOOLEAN(readByte() == 0 ? false : true); - case LITERALbyte: - return AConstant.BYTE((byte)readLong(len)); - case LITERALshort: - return AConstant.SHORT((short)readLong(len)); - case LITERALchar: - return AConstant.CHAR((char)readLong(len)); - case LITERALint: - return AConstant.INT((int)readLong(len)); - case LITERALlong: - return AConstant.LONG(readLong(len)); - case LITERALfloat: - return AConstant.FLOAT(Float.intBitsToFloat((int)readLong(len))); - case LITERALdouble: - return AConstant.DOUBLE(Double.longBitsToDouble(readLong(len))); - case LITERALstring: - return AConstant.STRING(readNameRef().toString()); - case LITERALnull: - return AConstant.NULL; - case LITERALzero: - return AConstant.ZERO; - default: - throw Debug.abort("illegal tag: " + tag); - } - } - - AConstant readConstantRef() { - int n = readNat(); - int savedBp = bp; - bp = index[n]; - AConstant constant = readConstant(); - bp = savedBp; - return constant; - } - - public static class BadSignature extends java.lang.Error { - public BadSignature(UnPickle outer, String msg) { - super(msg); - } - public BadSignature(UnPickle outer) { - this(outer, "malformed signature at " + outer.bp); - } - } - -// --- print symbl files ------------------------------------------------- - - private static String tag2string(int tag) { - switch (tag) { - case TERMname: return "TERMname"; - case TYPEname: return "TYPEname"; - case NONEsym: return "NONEsym"; - case TYPEsym: return "TYPEsym"; - case ALIASsym: return "ALIASsym"; - case CLASSsym: return "CLASSsym"; - case VALsym: return "VALsym"; - case EXTref: return "EXTref"; - case EXTMODCLASSref: return "EXTMODCLASSref"; - case NOtpe: return "NOtpe"; - case THIStpe: return "THIStpe"; - case SINGLEtpe: return "SINGLEtpe"; - case TYPEREFtpe: return "TYPEREFtpe"; - case CONSTANTtpe: return "CONSTANTtpe"; - case COMPOUNDtpe: return "COMPOUNDtpe"; - case METHODtpe: return "METHODtpe"; - case POLYtpe: return "POLYtpe"; - case OVERLOADEDtpe: return "OVERLOADEDtpe"; - case UNBOXEDtpe: return "UNBOXEDtpe"; - case UNBOXEDARRAYtpe: return "UNBOXEDARRAYtpe"; - case FLAGGEDtpe: return "FLAGGEDtpe"; - case ERRORtpe: return "ERRORtpe"; - case LITERALunit: return "LITERALunit"; - case LITERALboolean: return "LITERALboolean"; - case LITERALbyte: return "LITERALbyte"; - case LITERALshort: return "LITERALshort"; - case LITERALchar: return "LITERALchar"; - case LITERALint: return "LITERALint"; - case LITERALlong: return "LITERALlong"; - case LITERALfloat: return "LITERALfloat"; - case LITERALdouble: return "LITERALdouble"; - case LITERALstring: return "LITERALstring"; - case LITERALnull: return "LITERALnull"; - case LITERALzero: return "LITERALzero"; - default: return "***BAD TAG***(" + tag + ")"; - } - } - - private void print(PrintStream out) { - out.println("symbl attribute for " + classroot + ":"); - for (int i = 0; i < index.length; i++) { - out.print(i + "," + index[i] + ": "); - bp = index[i]; - int tag = readByte(); - out.print(tag2string(tag)); - int len = readNat(); - int end = len + bp; - out.print(" " + len); - switch (tag) { - case TERMname: - case TYPEname: - String name = SourceRepresentation.ascii2string(bytes, bp, len); - out.print(" " + SourceRepresentation.escape(name)); - bp = end; - break; - case NONEsym: - break; - case TYPEsym: - case ALIASsym: - case CLASSsym: - case VALsym: - out.print(" " + readNat()); //name - out.print(" " + readNat()); //owner - out.print(" " + Integer.toHexString(readNat())); //flags - out.print(" " + readNat()); //type - break; - case FLAGGEDtpe: - out.print(" " + Integer.toHexString(readNat())); //flags - } - while (bp < end) out.print(" " + readNat()); - out.println(); - } - } -} - diff --git a/sources/scalac/transformer/AddAccessorsPhase.java b/sources/scalac/transformer/AddAccessorsPhase.java deleted file mode 100644 index 2f684e1acb..0000000000 --- a/sources/scalac/transformer/AddAccessorsPhase.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: AddAccessorsPhase.java,v 1.1 2002/10/17 12:27:11 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Map; -import java.util.HashMap; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeList; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Debug; - - -/** - * This phase adds private accessor fields and methods for all class - * constructor arguments which are accessed from within the class' - * methods, or nested classes. - */ -public class AddAccessorsPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AddAccessorsPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - //######################################################################## - // Private Class - Tree transformer - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - /** The parameter to accessor method map */ - private final Map/*<Symbol,Symbol>*/ methods = new HashMap(); - - /** The current method */ - private Symbol method; - - /** Creates an accessor field symbol for given parameter. */ - private Symbol createAccessorField(Symbol param) { - int flags = Modifiers.PRIVATE | Modifiers.STABLE; - Name name = Name.fromString(param.name + "$"); - Symbol owner = param.owner().constructorClass(); - Symbol field = owner.newField(param.pos, flags, name); - field.setType(param.type()); - owner.members().enterOrOverload(field); - return field; - } - - /** Creates an accessor method symbol for given parameter. */ - private Symbol createAccessorMethod(Symbol param) { - int flags = Modifiers.PRIVATE | Modifiers.STABLE | Modifiers.ACCESSOR; - Name name = param.name; - Symbol owner = param.owner().constructorClass(); - Symbol method = owner.newMethod(param.pos, flags, name); - method.setType(Type.MethodType(Symbol.EMPTY_ARRAY, param.type())); - owner.members().enterOrOverload(method); - methods.put(param, method); - return method; - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, Template impl): { - Symbol clasz = tree.symbol(); - // transform parents and body - Symbol backup = this.method; - this.method = clasz.primaryConstructor(); - Tree[] parents = transform(impl.parents); - Tree[] body = transform(impl.body); - this.method = backup; - // create accessor field & method trees - TreeList accessors = new TreeList(); - Symbol[] params = clasz.valueParams(); - for (int i = 0; i < params.length; ++i) { - Symbol param = params[i]; - Symbol method = (Symbol)methods.remove(param); - if (method == null) continue; - Symbol field = createAccessorField(param); - accessors.append( - gen.ValDef( - field, - gen.Ident(param.pos, param))); - accessors.append( - gen.DefDef( - method, - gen.Select(gen.This(param.pos, clasz), field))); - } - body = Tree.concat(accessors.toArray(), body); - impl = gen.Template(clasz.pos, impl.symbol(), parents, body); - return gen.ClassDef(clasz, impl); - } - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - return Tree.Empty; // eliminate - case Typed(Tree expr, _): - return transform(expr); // eliminate - case DefDef(_, _, _, _, _, _): - Symbol backup = this.method; - this.method = tree.symbol(); - tree = super.transform(tree); - this.method = backup; - return tree; - case Ident(_): - Symbol symbol = tree.symbol(); - if (!symbol.owner().isPrimaryConstructor()) break; - if (symbol.owner() == this.method) break; - Symbol method = (Symbol)methods.get(symbol); - if (method == null) method = createAccessorMethod(symbol); - Tree qualifier = gen.This(tree.pos, method.owner()); - return gen.Apply(gen.Select(tree.pos, qualifier, method)); - } - return super.transform(tree); - } - - }; - - //######################################################################## -} diff --git a/sources/scalac/transformer/AddConstructors.java b/sources/scalac/transformer/AddConstructors.java deleted file mode 100644 index 5440c68ebf..0000000000 --- a/sources/scalac/transformer/AddConstructors.java +++ /dev/null @@ -1,295 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.util.ArrayList; -import java.util.HashMap; - -import scalac.Global; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolSubstTypeMap; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This phase adds to all classes one initializer method per - * constructor. Initializers have the same value parameters as their - * corresponding constructor but no type parameters. - * - * An initializer may be used in the body of another initializer - * either to invoke another initializer of the same class or to invoke - * an initailizer of the superclass. In that case, the initializer - * must appear in a Select node whose qualifier is either a This node - * or a Super node. The type of such a Select node is the type of the - * initializer. - * - * An initializer may also be used in a new operation. In that case, - * the initializer must appear in an Ident node. The type of such an - * Ident node is a PolyType whose arguments are the type arguments of - * the initializer's class and whose result type is the initializer's - * type. - * - * This phase does the following in the tree: - * - * - replaces all non-primary constructors definitions by initializer - * definitions with the same body, - * - * - for each non-interface class creates an primary initializer - * method corresponding to the primary constructor, - * - * - moves the call to the super constructor into the primary - * initializer, - * - * - moves all class fields initialization code (rhs of ValDefs) into - * the primary initializer, - * - * - moves all class-level expressions into the primary initializer, - * - * - replaces all constructor invocations by initializer invocations, - * except in the parents field of class templates. - * - * @author Nikolay Mihaylov - * @version 1.2 - */ -public class AddConstructors extends GenTransformer { - - /** A constructor to initializer map */ - private final HashMap/*<Symbol,Symbol>*/ initializers; - - /** A constructor to initializer parameter substitution */ - private final SymbolSubstTypeMap subst; - - /** The current primary initializer or null */ - private Symbol primaryInitializer; - - /** - * ... - * - * @param global - * @param initializers - */ - public AddConstructors(Global global, HashMap initializers) { - super(global); - this.initializers = initializers; - this.subst = new SymbolSubstTypeMap(); - } - - /** - * Returns the initializer corresponding to the given constructor. - * - * @param constructor - * @return - */ - private Symbol getInitializer(Symbol constructor) { - assert constructor.isConstructor(): Debug.show(constructor); - Symbol initializer = (Symbol)initializers.get(constructor); - if (initializer == null) { - assert !constructor.constructorClass().isInterface(): - "found interface constructor " + Debug.show(constructor); - int flags = constructor.isPrivate() - ? (constructor.flags & ~Modifiers.PRIVATE) | Modifiers.PROTECTED - : constructor.flags; - initializer = constructor.constructorClass().newMethod( - constructor.pos, - flags & Modifiers.ACCESSFLAGS, - constructor.name); - initializer.setInfo( - Type.MethodType( - constructor.valueParams(), - global.definitions.void_TYPE()) - .cloneType(constructor, initializer)); - initializer.owner().members().enterOrOverload(initializer); - initializers.put(constructor, initializer); - } - return initializer; - } - - /** - * Process the tree. - */ - public Tree transform(Tree tree) { - return transform(tree, false); - } - - /** - * ... - * - * @param tree - * @param inNew - * @return - */ - private Tree transform(Tree tree, boolean inNew) { - switch (tree) { - case ClassDef(_, _, _, _, _, Template impl): - Symbol clasz = tree.symbol(); - - if (clasz.isInterface()) - return gen.ClassDef(clasz, transform(impl.body)); - - // expressions that go before the call to the super constructor - final ArrayList constrBody = new ArrayList(); - - // expressions that go after the call to the super constructor - final ArrayList constrBody2 = new ArrayList(); - - // the body of the class after the transformation - final ArrayList classBody = new ArrayList(); - - Symbol local = impl.symbol(); - for (int i = 0; i < impl.body.length; i++) { - Tree member = impl.body[i]; - if (member.definesSymbol() && member.symbol().owner()!=local) { - switch (member) { - case ValDef(_, _, _, Tree rhs): - // move initialization code into initializer - Symbol field = member.symbol(); - if (rhs == Tree.Empty) break; - member = gen.ValDef(field, Tree.Empty); - Tree assign = gen.Assign( - gen.Select(gen.This(member.pos, clasz),field),rhs); - if (rhs.hasSymbol() && rhs.symbol().isParameter()) { - constrBody.add(assign); - } else { - constrBody2.add(assign); - } - } - classBody.add(member); - } else { - // move class-level code into initializer - constrBody2.add(member); - } - } - - // inline the call to the super constructor - for (int i = 0; i < impl.parents.length; i++) { - switch (impl.parents[i]) { - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] args): - assert fun.symbol().isConstructor(): impl.parents[i]; - if (fun.symbol().constructorClass().isInterface()) continue; - int pos = impl.parents[i].pos; - Tree superConstr = gen.Select - (gen.Super(pos, clasz), getInitializer(fun.symbol())); - constrBody.add(gen.mkApply_V(superConstr, args)); - break; - case Apply(Tree fun, Tree[] args): - assert fun.symbol().isConstructor(): impl.parents[i]; - if (fun.symbol().constructorClass().isInterface()) continue; - int pos = impl.parents[i].pos; - Tree superConstr = gen.Select - (gen.Super(pos, clasz), getInitializer(fun.symbol())); - constrBody.add(gen.mkApply_V(superConstr, args)); - break; - default: - throw Debug.abort("illegal case", impl.parents[i]); - } - } - - // add valdefs and class-level expression to the constructor body - constrBody.addAll(constrBody2); - - Tree constrTree = gen.mkUnitBlock( - clasz.primaryConstructor().pos, - (Tree[])constrBody.toArray(new Tree[constrBody.size()])); - - classBody.add(gen.DefDef(clasz.primaryConstructor(), constrTree)); - - Tree[] newBody = (Tree[]) classBody.toArray(Tree.EMPTY_ARRAY); - - // transform the bodies of all members in order to substitute - // the constructor references with the new ones - return gen.ClassDef(clasz, transform(newBody)); - - case DefDef(_, _, _, _, _, Tree rhs): - if (!tree.symbol().isConstructor()) return super.transform(tree); - // replace constructor by initializer - Symbol constructor = tree.symbol(); - Symbol initializer = getInitializer(constructor); - subst.insertSymbol( - constructor.typeParams(), - constructor.constructorClass().typeParams()); - subst.insertSymbol( - constructor.valueParams(), - initializer.valueParams()); - if (constructor.isPrimaryConstructor()) - primaryInitializer = initializer; - rhs = transform(rhs); - primaryInitializer = null; - subst.removeSymbol(constructor.valueParams()); - subst.removeSymbol(constructor.typeParams()); - // add consistent result expression - rhs = gen.mkUnitBlock(rhs); - return gen.DefDef(initializer, rhs); - - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol symbol = tree.symbol(); - if (symbol.owner().isConstructor()) { - // update symbols like x in these examples - // ex 1: class C { { val x = ...; ... } } - // ex 2: class C { def this(i: Int) { val x = i; ... } } - symbol.setOwner(getInitializer(symbol.owner())); - symbol.updateInfo(subst.apply(symbol.info())); - } - return super.transform(tree); - - case New(Tree init): - return gen.New(transform(init, true)); - - case TypeApply(Tree fun, Tree[] args): - if (!fun.symbol().isConstructor()) return super.transform(tree); - if (!inNew) return transform(fun); - assert fun instanceof Tree.Ident: tree; - return transform(tree, fun.symbol(), transform(args)); - - case Apply(Tree fun, Tree[] args): - return gen.Apply(transform(fun, inNew), transform(args)); - - case Ident(_): - Symbol symbol = tree.symbol(); - if (inNew) return transform(tree, symbol, Tree.EMPTY_ARRAY); - if (symbol.isConstructor()) { - symbol = getInitializer(symbol); - Symbol clasz = symbol.owner(); - return gen.Select(gen.This(tree.pos, clasz), symbol); - } - else if (symbol.owner().isConstructor()) { - symbol = subst.lookupSymbol(symbol); - } - return gen.Ident(tree.pos, symbol); - - case TypeTerm(): - return gen.TypeTerm(tree.pos, subst.apply(tree.getType())); - - default: - return super.transform(tree); - } // switch(tree) - - } // transform() - - /** - * Transforms the new instance creation. - * - * @param tree - * @param constructor - * @param targs - * @return - */ - private Tree transform(Tree tree, Symbol constructor, Tree[] targs) { - assert constructor.isConstructor(): tree; - Symbol initializer = getInitializer(constructor); - Symbol clasz = initializer.owner(); - Tree instance = gen.Create(tree.pos, Tree.Empty, clasz, targs); - return gen.Select(tree.pos, instance, initializer); - } - -} // class AddConstructors diff --git a/sources/scalac/transformer/AddConstructorsPhase.java b/sources/scalac/transformer/AddConstructorsPhase.java deleted file mode 100644 index 1dfb10e344..0000000000 --- a/sources/scalac/transformer/AddConstructorsPhase.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -//package scala.compiler.backend; -package scalac.transformer; - -import java.util.HashMap; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -public class AddConstructorsPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from old constructor symbols to new ones */ - private final HashMap/*<Symbol,Symbol>*/ constructors = new HashMap(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AddConstructorsPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given type for the given symbol. */ - public Type transformInfo(Symbol symbol, Type type) { - if (symbol.isConstructor()) { - switch (type) { - case PolyType(Symbol[] tparams, MethodType(_, Type result)): - result = Type.MethodType(Symbol.EMPTY_ARRAY, result); - return Type.PolyType(tparams, result); - case MethodType(_, Type result): - return Type.MethodType(Symbol.EMPTY_ARRAY, result); - default: - throw Debug.abort("illegal case", type); - } - } - return type; - } - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - new AddConstructors(global, constructors).apply(unit); - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java deleted file mode 100644 index 1e922a8165..0000000000 --- a/sources/scalac/transformer/AddInterfaces.java +++ /dev/null @@ -1,304 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -// TODO find a good way to change symbol flags (PRIVATE, DEFERRED, -// INTERFACE). In particular find how to make sure that the -// modifications are not made too early, for example before the symbol -// is cloned. - -package scalac.transformer; - -import java.util.Map; -import java.util.HashMap; - -import scalac.Global; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeGen; -import scalac.ast.TreeList; -import scalac.symtab.Type; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolSubstTypeMap; -import scalac.util.Debug; - -/** - * Add, for each class, an interface with the same name, to be used - * later by mixin expansion. More specifically: - * - * - at the end of the name of every class, the string "$class" is - * added, - * - * - an interface with the original name of the class is created, and - * contains all directly bound members of the class (as abstract - * members), - * - * - the interface is added to the mixin base classes of the class. - * - * @author Michel Schinz - * @version 1.0 - */ -public class AddInterfaces extends GenTransformer { - - //######################################################################### - // Private Fields - - /** The AddInterface phase */ - private final AddInterfacesPhase phase; - - /** The current class (null is none) */ - private Symbol clasz; - - /** The current member (null is none) */ - private Symbol member; - - /** The current class substitution (null is none) */ - private Type.Map classSubst; - - /** The current parameter substitution (null is none) */ - private SymbolSubstTypeMap paramSubst; - - //######################################################################### - // Public Constructors - - /** Initializes this instance. */ - public AddInterfaces(Global global, AddInterfacesPhase phase) { - super(global); - this.phase = phase; - } - - //######################################################################### - // Public Methods - - /** Transforms the given symbol. - * - * @param tree - * @return - */ - public Symbol getSymbolFor(Tree tree) { - switch (tree) { - case Create(_, _): - return phase.getClassSymbol(tree.symbol()); - case Return(_): - return member; - case This(_): - case Super(_, _): - return clasz; - case Select(Super(_, _), _): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - return getClassMember(symbol, true); - case Select(_, _): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - return symbol; - case Ident(_): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - if (symbol.isParameter() && !symbol.owner().isStatic()) - return getClassVParam(symbol); - return symbol; - default: - return tree.symbol(); - } - } - - /** Transforms the given type. */ - public Type transform(Type type) { - if (classSubst != null) type = classSubst.apply(type); - if (paramSubst != null) type = paramSubst.apply(type); - return type; - } - - /** Transforms the given trees. */ - public Tree[] transform(Tree[] trees) { - if (member != null) return super.transform(trees); - TreeList list = new TreeList(); - for (int i = 0; i < trees.length; i++) template(list, trees[i]); - return list.toArray(); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol symbol = tree.symbol(); - if (symbol.owner() != member) { - symbol.updateInfo(transform(symbol.info())); - symbol.setOwner(member); - } - return super.transform(tree); - case Select(Tree qualifier, _): - Type prefix = qualifier.type(); - qualifier = transform(qualifier); - Symbol symbol = getSymbolFor(tree); - if (symbol.isJava() && !symbol.owner().isInterface()) { - if (qualifier.type().widen().symbol().isInterface()) { - Type baseType = prefix.baseType(symbol.owner()); - assert baseType != Type.NoType: tree; - qualifier = gen.mkAsInstanceOf(qualifier, baseType); - } - } - return gen.Select(tree.pos, qualifier, symbol); - default: - return super.transform(tree); - } - } - - //######################################################################### - // Private Methods - - /** Transforms the given template and adds it to given list. - * - * @param trees - * @param tree - */ - private void template(TreeList trees, Tree tree) { - switch (tree) { - case Empty: - return; - case PackageDef(_, _): - trees.append(super.transform(tree)); - return; - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - TreeList list = new TreeList(transform(body)); - this.clasz = tree.symbol(); - Map methods = new HashMap(); - if (phase.needInterface(clasz)) { - Symbol clone = phase.getClassSymbol(clasz); - trees.append(getClassTree(clasz, list, methods)); - list = new TreeList(); - this.classSubst = new Type.SubstThisMap(clasz, clone); - this.paramSubst = phase.getClassSubst(clone); - this.clasz = clone; - } - for (int i = 0; i < body.length; i++) member(methods, body[i]); - trees.append(getClassTree(clasz, list, methods)); - assert methods.isEmpty(): Debug.show(methods.keySet().toArray()); - this.paramSubst = null; - this.classSubst = null; - this.clasz = null; - return; - case DefDef(_, _, _, _, _, _): - case ValDef(_, _, _, _): - return; - default: - throw Debug.abort("illegal tree", tree); - } - } - - /** - * Transforms the given class member. Methods with a non-empty - * body are added to the given method map. All other members are - * dropped. - * - * @param methods - * @param tree - */ - private void member(Map methods, Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - return; - case DefDef(_, _, _, _, _, Tree rhs): - if (rhs == Tree.Empty) return; - Symbol symbol = tree.symbol(); - this.member = getClassMember(symbol); - if (member != symbol) { - paramSubst.insertSymbol( - symbol.typeParams(), member.nextTypeParams()); - paramSubst.insertSymbol( - symbol.valueParams(), member.nextValueParams()); - } - methods.put(member, gen.DefDef(member, transform(rhs))); - if (member != symbol) { - paramSubst.removeSymbol(symbol.valueParams()); - paramSubst.removeSymbol(symbol.typeParams()); - } - this.member = null; - return; - case ValDef(_, _, _, Tree rhs): - assert rhs == Tree.Empty: tree; - return; - default: - throw Debug.abort("illegal tree", tree); - } - } - - /** - * Returns the tree of the given class. Its body is built by - * adding its members to the provided body. Non-abstract methods - * are removed from the provided method map. All other members are - * generated from their symbol. - * - * @param clasz - * @param body - * @param methods - * @return - */ - private Tree getClassTree(Symbol clasz, TreeList body, Map methods) { - Scope members = clasz.nextInfo().members(); - for (Scope.SymbolIterator i = members.iterator(); i.hasNext(); ) { - Symbol member = i.next(); - if (!member.isTerm()) continue; - body.append(getMemberTree(clasz, member, methods)); - } - Tree[] array = body.toArray(); - if (!clasz.isInterface()) phase.classToBody.put(clasz, array); - return gen.ClassDef(clasz, array); - } - - /** - * Returns the tree of the given member. Non-abstract methods are - * removed from the given method map. All other members are - * generated from their symbol. - * - * @param clasz - * @param member - * @param methods - * @return - */ - private Tree getMemberTree(Symbol clasz, Symbol member, Map methods) { - if (!member.isMethod()) return gen.ValDef(member, Tree.Empty); - if (member.isDeferred()) return gen.DefDef(member, Tree.Empty); - Tree method = (Tree)methods.remove(member); - assert method != null: Debug.show(clasz + "." + member + ":" + member.info() + member.locationString()); - return method; - } - - /** Returns the symbol of given parameter in current class. - * - * @param vparam - * @return - */ - private Symbol getClassVParam(Symbol vparam) { - if (paramSubst == null) return vparam; - Symbol clone = (Symbol)paramSubst.lookupSymbol(vparam); - assert clone != null: Debug.show(vparam, clasz, member); - return clone; - } - - /** Returns the symbol of given member in current class. */ - private Symbol getClassMember(Symbol member) { - return getClassMember(member, false); - } - // !!! Try to remove version with lazy argument. It is currently - // needed for super calls to abstract method (possible in mixins). - private Symbol getClassMember(Symbol member, boolean lazy) { - Symbol owner = member.owner(); - assert owner.isClass(): Debug.show(member); - if (!phase.needInterface(owner)) return member; - Symbol clasz = phase.getClassSymbol(owner); - Symbol clone = (Symbol)phase.getClassMemberMap(clasz).get(member); - assert clone != null || lazy: Debug.show(member, " not in ", clasz); - return clone != null ? clone : member; - } - - //######################################################################### -} diff --git a/sources/scalac/transformer/AddInterfacesPhase.java b/sources/scalac/transformer/AddInterfacesPhase.java deleted file mode 100644 index 026ac5feda..0000000000 --- a/sources/scalac/transformer/AddInterfacesPhase.java +++ /dev/null @@ -1,313 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -// TODO try to use setInfo instead of updateInfo for cloned symbols, -// to avoid the need to use nextPhase/nextInfo. - -package scalac.transformer; - -import java.util.HashMap; -import java.util.Map; - -import scalac.*; -import scalac.symtab.*; -import scalac.util.Debug; -import scalac.util.Name; - -public class AddInterfacesPhase extends Phase { - - /** Initializes this instance. */ - public AddInterfacesPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - new AddInterfaces(global, this).apply(unit); - } - - public Type transformInfo(Symbol sym, Type tp) { - if (sym.isConstructor() || sym.owner().isConstructor()) { - return tp; - } else if (sym.isClass() && !sym.isJava()) { - Definitions definitions = global.definitions; - if (sym == definitions.ANY_CLASS) return tp; - Type[] oldParents = tp.parents(); - assert oldParents.length > 0 : Debug.show(sym); - for (int i = 1; i < oldParents.length; ++i) { - Symbol oldSym = oldParents[i].symbol(); - assert !oldSym.isJava() || oldSym.isInterface() : - Debug.show(sym) + " <: " + Debug.show(oldSym); - } - - boolean ifaceReqrd = needInterface(sym); - Type[] newParents; - Scope newMembers = new Scope(); - - Scope.SymbolIterator oldMembersIt = - tp.members().iterator(); - while (oldMembersIt.hasNext()) { - Symbol member = oldMembersIt.next(); - - if (ifaceReqrd - && (member.isInitializer() || !memberGoesInInterface(member))) - continue; - - if (member.isPrivate() && !member.isClass()) { - member.name = uniqueName(member); - member.flags ^= Modifiers.PRIVATE; - } else if (member.isProtected()) - member.flags ^= Modifiers.PROTECTED; - - newMembers.enterOrOverload(member); - } - - if (ifaceReqrd) { - // Before this phase, the symbol is a class, but after - // it will be an interface. Its type has to be changed - // so that: - // - // 1. Java classes are removed from its parents, - // - // 2. only members which will end up in the - // interface are kept, and private ones are made - // public and renamed. - sym.flags |= Modifiers.INTERFACE; - newParents = oldParents; - } else { - // The symbol is the one of a class which doesn't need - // an interface. We need to fix its parents to use - // class symbols instead of interface symbols. - newParents = new Type[oldParents.length]; - for (int i = 0; i < oldParents.length; ++i) { - switch (oldParents[i]) { - case TypeRef(Type pre, Symbol oldSym, Type[] args): - newParents[i] = !needInterface(oldSym) - ? oldParents[i] - : Type.typeRef(pre, getClassSymbol(oldSym), args); - break; - default: - throw Debug.abort("illegal case", oldParents[i]); - } - } - } - - return Type.compoundType(newParents, newMembers, sym); - } else if (sym.owner().isClass() || sym.isParameter()) { - getClassSymbol(sym.enclClass()); - return sym.info(); - } else - return tp; - } - - protected boolean memberGoesInInterface(Symbol member) { - return !member.isStatic() && (member.isType() || member.isMethod()); - } - - protected final SymbolNameWriter uniqueNameWriter = new SymbolNameWriter() - .setAllSeparators('$') - .setRootSeparator('\0'); - protected Name uniqueName(Symbol sym) { - Name name = Name.fromString(uniqueNameWriter.toString(sym)); - return sym.name.isTypeName() ? name.toTypeName() : name; - } - - // Terminology: in the following code, the symbol which was used - // until this phase for the class, and will now be used for the - // interface is called the "interface symbol". The symbol created - // by this phase for the class is called the "class symbol". - - /** True iff the given class symbol needs an interface. */ - protected boolean needInterface(Symbol classSym) { - assert classSym.isClass() - : Debug.show(classSym) + " is not a class (kind " + classSym.kind + ")"; - return !(classSym.isJava() - || classSym.isModuleClass() - || classSym.isAnonymousClass() - || hasInterfaceSymbol(classSym) - || classSym == global.definitions.ANY_CLASS - || classSym == global.definitions.ANYREF_CLASS - || classSym == global.definitions.ALL_CLASS - || classSym == global.definitions.ALLREF_CLASS); - } - - protected final static String CLASS_SUFFIX = "$class"; - protected Name className(Name ifaceName) { - Name className = Name.fromString(ifaceName.toString() + CLASS_SUFFIX); - if (ifaceName.isTypeName()) return className.toTypeName(); - else return className; - } - - protected final HashMap/*<Symbol,Symbol>*/ ifaceToClass = new HashMap(); - protected final HashMap/*<Symbol,Symbol>*/ classToIFace = new HashMap(); - protected final HashMap/*<Symbol,Tree[]>*/ classToBody = new HashMap(); - - /** Return the class symbol corresponding to the given interface - * symbol. If the class does not need an interface, return the - * given symbol. - * - * @param ifaceSym - * @return - */ - protected Symbol getClassSymbol(Symbol ifaceSym) { - assert ifaceSym.isClass(): Debug.show(ifaceSym); - if (!needInterface(ifaceSym)) - return ifaceSym; - - Symbol classSym = (Symbol)ifaceToClass.get(ifaceSym); - if (classSym == null) { - classSym = ifaceSym.cloneSymbol(ifaceSym.owner()); - classSym.name = className(ifaceSym.name); - ifaceSym.flags &= ~Modifiers.FINAL; - classSym.flags &= ~Modifiers.INTERFACE; - - Scope ifaceOwnerMembers = ifaceSym.owner().members(); - ifaceOwnerMembers.enter(classSym); - - Type.SubstThisMap thisTypeMap = - new Type.SubstThisMap(ifaceSym, classSym); - - // Create class substitution map. - SymbolSubstTypeMap classSubst = newClassSubst(classSym); - Map classMemberMap = newClassMemberMap(classSym); - - Symbol[] ifaceTParams = ifaceSym.typeParams(); - Symbol[] classTParams = classSym.typeParams(); - classSubst.insertSymbol(ifaceTParams, classTParams); - - // Clone all members, entering them in the class scope. - Scope classMembers = new Scope(); - Scope.SymbolIterator ifaceMembersIt = - ifaceSym.members().iterator(); - while (ifaceMembersIt.hasNext()) { - Symbol ifaceMemberSym = ifaceMembersIt.next(); - - if (ifaceMemberSym.isType() - || ifaceMemberSym.isDeferred()) - continue; - - Symbol classMemberSym; - if (memberGoesInInterface(ifaceMemberSym)) { - if (ifaceMemberSym.isPrivate()) { - ifaceMemberSym.name = uniqueName(ifaceMemberSym); - ifaceMemberSym.flags |= Modifiers.FINAL; - ifaceMemberSym.flags ^= Modifiers.PRIVATE; - } else if (ifaceMemberSym.isProtected()) - ifaceMemberSym.flags ^= Modifiers.PROTECTED; - - classMemberSym = ifaceMemberSym.cloneSymbol(classSym); - ifaceMemberSym.flags &= ~Modifiers.FINAL; - classMemberSym.setInfo( - thisTypeMap.applyParams( - classSubst.applyParams( - classMemberSym.info().cloneType( - ifaceMemberSym, classMemberSym)))); - - ifaceMemberSym.flags |= Modifiers.DEFERRED; - } else { - // Member doesn't go in interface, we just make it - // owned by the class. - classMemberSym = ifaceMemberSym; - - // [HACK] the following forces the evaluation of - // the type of all value parameters, which might - // otherwise become invalid once the owner is - // changed. - classMemberSym.info(); - if (classMemberSym.isMethod()) { - Symbol[] vp = classMemberSym.valueParams(); - for (int i = 0; i < vp.length; ++i) - vp[i].info(); - } - - classMemberSym.setOwner(classSym); - classMemberSym.updateInfo( - thisTypeMap.apply( - classSubst.apply( - classMemberSym.info()))); - } - - classMemberMap.put(ifaceMemberSym, classMemberSym); - classMembers.enterOrOverload(classMemberSym); - } - - // Give correct type to the class symbol by using class - // symbols for its parents, and by adding the interface - // among them. - Type[] oldClassParents = classSym.parents(); - int oldParentsCount = oldClassParents.length; - Type[] newClassParents = new Type[oldParentsCount + 1]; - for (int i = 0; i < oldParentsCount; ++i) { - switch (oldClassParents[i]) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Type newTp = Type.typeRef(pre, getClassSymbol(sym), args); - newClassParents[i] = classSubst.apply(newTp); - break; - default: - throw Debug.abort("unexpected type for parent", oldClassParents[i]); - } - } - newClassParents[oldParentsCount] = classSubst.apply(ifaceSym.type()); - // TODO setInfo cannot be used here because the type then - // goes through transformInfo. Maybe setInfo should behave - // like updateInfo. - classSym.updateInfo(Type.compoundType(newClassParents, - classMembers, - classSym)); - ifaceToClass.put(ifaceSym, classSym); - classToIFace.put(classSym, ifaceSym); - - // move attributes to the implementing class - AttributeInfo attr = global.removeAttributes(ifaceSym); - if (attr != null) { - global.setAttribute(classSym, attr); - } - } - return classSym; - } - - public boolean hasInterfaceSymbol(Symbol classSym) { - return classToIFace.containsKey(classSym); - } - - public Symbol getInterfaceSymbol(Symbol classSym) { - return (Symbol)classToIFace.get(classSym); - } - - HashMap/*<Symbol,SymbolSubstTypeMap>*/ classSubstitutions = new HashMap(); - protected SymbolSubstTypeMap newClassSubst(Symbol classSym) { - SymbolSubstTypeMap subst = new SymbolSubstTypeMap(); - classSubstitutions.put(classSym, subst); - return subst; - } - - /** Return symbol substitution for the class (a mapping from the - * interface's type and value parameters to the class' equivalent) - */ - public SymbolSubstTypeMap getClassSubst(Symbol classSym) { - SymbolSubstTypeMap classSubst = - (SymbolSubstTypeMap)classSubstitutions.get(classSym); - assert classSubst != null; - return classSubst; - } - - HashMap/*<Symbol, HashMap>*/ classMemberMaps = new HashMap(); - protected HashMap newClassMemberMap(Symbol classSym) { - HashMap map = new HashMap(); - classMemberMaps.put(classSym, map); - return map; - } - - /** Return symbol substitution for the class (a mapping from the - * interface's type and value parameters to the class' equivalent) - */ - public Map getClassMemberMap(Symbol classSym) { - return (Map)classMemberMaps.get(classSym); - } - -} diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java deleted file mode 100644 index 67a462b1f4..0000000000 --- a/sources/scalac/transformer/Erasure.java +++ /dev/null @@ -1,759 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Erasure.java,v 1.48 2003/01/16 14:21:19 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; - -import scalac.Global; -import scalac.Phase; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.Ident; -import scalac.ast.Tree.Template; -import scalac.ast.Tree.AbsTypeDef; -import scalac.ast.Tree.AliasTypeDef; -import scalac.ast.Tree.ValDef; -import scalac.ast.TreeList; -import scalac.ast.GenTransformer; -import scalac.atree.AConstant; -import scalac.symtab.Definitions; -import scalac.symtab.Kinds; -import scalac.symtab.Type; -import scalac.symtab.TypeTags; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.SymSet; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolTablePrinter; -import scalac.backend.Primitive; -import scalac.backend.Primitives; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -/** A transformer for type erasure and bridge building - * - * @author Martin Odersky - * @version 1.0 - * - * What it does: - * (1) Map every type to its erasure. - * (2) If method A overrides a method B, and the erased type ETA of A is - * different from the erased type ETB of B seen as a member of A's class, - * add a bridge method with the same name as A,B, with signature ETB - * which calls A after casting parameters. - */ -public class Erasure extends GenTransformer implements Modifiers { - - //######################################################################## - // Private Constants - - /** The unboxed types */ - private static final Type - UNBOXED_UNIT = Type.unboxedType(TypeTags.UNIT), - UNBOXED_BOOLEAN = Type.unboxedType(TypeTags.BOOLEAN), - UNBOXED_BYTE = Type.unboxedType(TypeTags.BYTE), - UNBOXED_SHORT = Type.unboxedType(TypeTags.SHORT), - UNBOXED_CHAR = Type.unboxedType(TypeTags.CHAR), - UNBOXED_INT = Type.unboxedType(TypeTags.INT), - UNBOXED_LONG = Type.unboxedType(TypeTags.LONG), - UNBOXED_FLOAT = Type.unboxedType(TypeTags.FLOAT), - UNBOXED_DOUBLE = Type.unboxedType(TypeTags.DOUBLE); - - //######################################################################## - // Private Fields - - /** The global definitions */ - private final Definitions definitions; - - /** The global primitives */ - private final Primitives primitives; - - /** The current unit */ - private CompilationUnit unit; - - private final boolean forMSIL; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public Erasure(Global global) { - super(global); - this.definitions = global.definitions; - this.primitives = global.primitives; - this.forMSIL = global.target == global.TARGET_MSIL; - } - - //######################################################################## - // Public Methods - - /** Transforms the given unit. */ - public void apply(CompilationUnit unit) { - this.unit = unit; - super.apply(unit); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - Symbol clasz = tree.symbol(); - TreeList members = new TreeList(transform(body)); - addBridges(clasz, members); - return gen.ClassDef(clasz, members.toArray()); - - case ValDef(_, _, _, Tree rhs): - Symbol field = tree.symbol(); - if (rhs != Tree.Empty) rhs = transform(rhs, field.nextType()); - return gen.ValDef(field, rhs); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol method = tree.symbol(); - if (rhs != Tree.Empty) - rhs = transform(rhs, method.nextType().resultType()); - return gen.DefDef(method, rhs); - - case LabelDef(_, Ident[] params, Tree body): - Symbol label = tree.symbol(); - body = transform(body, label.nextType().resultType()); - return gen.LabelDef(label, Tree.symbolOf(params), body); - - case Assign(Tree lhs, Tree rhs): - lhs = transform(lhs); - rhs = transform(rhs, lhs.type); - return gen.Assign(tree.pos, lhs, rhs); - - case Return(Tree expr): - Symbol method = tree.symbol(); - Type type = method.nextType().resultType(); - return gen.Return(tree.pos, method, transform(expr, type)); - - case New(Tree init): - if (tree.getType().symbol() == definitions.ARRAY_CLASS) { - switch (init) { - case Apply(_, Tree[] args): - assert args.length == 1: tree; - Type element = getArrayElementType(tree.getType()).erasure(); - Tree size = transform(args[0]); - return genNewUnboxedArray(tree.pos, element, size); - default: - throw Debug.abort("illegal case", tree); - } - } - return gen.New(tree.pos, transform(init)); - - case Create(_, _): - return gen.Create(tree.pos, Tree.Empty, tree.symbol()); - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - fun = transform(fun); - vargs = transform(vargs); - Symbol symbol = fun.symbol(); - if (symbol == definitions.ANY_AS_ERASED) { - assert targs.length == 1 && vargs.length == 0: tree; - return coerce(getQualifier(fun), targs[0].getType().erasure()); - } - if (symbol == definitions.ANY_IS_ERASED) { - assert targs.length == 1 && vargs.length == 0: tree; - Type type = targs[0].type.erasure(); - if (isUnboxedSimpleType(type)) type = targs[0].type; - return gen.mkIsInstanceOf(tree.pos, getQualifier(fun), type); - } - return genApply(tree.pos, fun, vargs); - - case Apply(Tree fun, Tree[] vargs): - fun = transform(fun); - vargs = transform(vargs); - switch (fun) { - case Select(Apply(Tree bfun, Tree[] bargs), _): - Symbol bsym = bfun.symbol(); - if (primitives.getPrimitive(bsym) != Primitive.BOX) break; - assert bargs.length == 1: fun; - switch (primitives.getPrimitive(fun.symbol())) { - case COERCE: - assert vargs.length == 0: tree; - Tree value = bargs[0]; - return coerce(value, fun.type().resultType()); - case LENGTH: - assert vargs.length == 0: tree; - Tree array = bargs[0]; - return genUnboxedArrayLength(tree.pos, array); - case APPLY: - assert vargs.length == 1: tree; - Tree array = bargs[0]; - Tree index = vargs[0]; - return genUnboxedArrayGet(tree.pos, array, index); - case UPDATE: - assert vargs.length == 2: tree; - Tree array = bargs[0]; - Tree index = vargs[0]; - Tree value = vargs[1]; - return genUnboxedArraySet(tree.pos, array, index, value); - } - } - return genApply(tree.pos, fun, vargs); - - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - Type prefix = qualifier.type().baseType(symbol.owner()).erasure(); - assert prefix != Type.NoType: tree + " -- " + Debug.show(symbol); - qualifier = transform(qualifier); - qualifier = coerce(qualifier, prefix); - - // Might end up with "box(unbox(...))". That's needed by backend. - if (isUnboxedType(prefix)) qualifier = box(qualifier, true); - return gen.Select(tree.pos, qualifier, symbol); - - case Literal(AConstant.ZERO): - return gen.mkNullLit(tree.pos); - - case Block(_, _): - case If(_, _, _): - case Switch(_, _, _, _): - return transform(tree, tree.getType().fullErasure()); - - default: - return super.transform(tree); - } - } - - //######################################################################## - // Private Methods - Tree transformation - - /** Transforms the given trees with given prototype. */ - private Tree[] transform(Tree[] trees, Type pt) { - for (int i = 0; i < trees.length; i++) { - Tree tree = transform(trees[i], pt); - if (tree == trees[i]) continue; - Tree[] array = new Tree[trees.length]; - for (int j = 0; j < i ; j++) array[j] = trees[j]; - array[i] = tree; - while (++i < trees.length) array[i] = transform(trees[i], pt); - return array; - } - return trees; - } - - /** Transforms the given tree with given prototype. */ - private Tree transform(Tree tree, Type pt) { - switch (tree) { - - case Block(Tree[] stats, Tree value): - return gen.Block(tree.pos, transform(stats), transform(value, pt)); - - case If(Tree cond, Tree thenp, Tree elsep): - cond = transform(cond, UNBOXED_BOOLEAN); - thenp = transform(thenp, pt); - elsep = transform(elsep, pt); - return gen.If(tree.pos, cond, thenp, elsep, pt); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - test = transform(test, UNBOXED_INT); - bodies = transform(bodies, pt); - otherwise = transform(otherwise, pt); - return gen.Switch(tree.pos, test, tags, bodies, otherwise, pt); - - case Return(_): - // !!! why do we build a block here? - Tree value = transform(gen.mkDefaultValue(tree.pos, pt), pt); - return gen.mkBlock(transform(tree), value); - - case LabelDef(_, _, _): - case Assign(_, _): - case New(_): - case Apply(_, _): - case Super(_, _): - case This(_): - case Select(_, _): - case Ident(_): - case Literal(_): - return coerce(transform(tree), pt); - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Transforms Unit literal with given prototype. */ - private Tree transformUnit(int pos, Type pt) { - Tree unit = pt.isSameAs(UNBOXED_UNIT) - ? gen.mkUnitLit(pos) - : gen.mkApply__(gen.mkGlobalRef(pos, primitives.BOX_UVALUE)); - return coerce(unit, pt); - } - - /** Coerces the given tree to the given type. */ - private Tree coerce(Tree tree, Type pt) { - if (isSubType(tree.type(), pt)) { - if (tree.type().symbol() == definitions.ARRAY_CLASS) { - if (pt.symbol() != definitions.ARRAY_CLASS) { - Symbol symbol = primitives.UNBOX__ARRAY; - Tree unboxtree = gen.mkGlobalRef(tree.pos, symbol); - tree = gen.mkApply_V(unboxtree, new Tree[] {tree}); - return coerce(tree, pt); - } - } - return tree; - } - if (isUnboxedSimpleType(tree.type())) { - if (isUnboxedSimpleType(pt)) return convert(tree, pt); - Type to = pt.erasure(); - if (!isUnboxedSimpleType(to) || isSameAs(to, tree.type())) - return box(tree); - else - return coerce(convert(tree, to), pt); - } else if (isUnboxedArrayType(tree.type())) { - if (!isUnboxedArrayType(pt)) return check(box(tree), pt); - } else if (isUnboxedSimpleType(pt)) { - Type from = tree.type().erasure(); - if (isUnboxedSimpleType(from)) - return convert(unbox(tree, from), pt); - else - return unbox(coerce(tree, boxUnboxedType(pt)), pt); - } else if (isUnboxedArrayType(pt)) { - if (tree.type.symbol() == definitions.ARRAY_CLASS) - return coerce(unbox(tree, pt), pt); - } else if (pt.symbol() == definitions.ARRAY_CLASS) { - Tree boxtree = gen.mkGlobalRef(tree.pos, primitives.BOX__ARRAY); - return gen.mkApply_V(boxtree, new Tree[]{tree}); - } - return gen.mkAsInstanceOf(tree, pt); - } - - /** Checks that the given tree is of the given type. */ - private Tree check(Tree tree, Type pt) { - assert isSubType(tree.type(), pt): tree +" - "+ tree.type() +" - "+pt; - return tree; - } - - - /** Boxes the given tree. */ - private Tree box(Tree tree) { - return box(tree, false); - } - - /** Boxes the given tree. */ - private Tree box(Tree tree, boolean force) { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (primitives.getPrimitive(fun.symbol()) == Primitive.UNBOX) { - assert args.length == 1: tree; - if (!force) return args[0]; - } - } - Symbol symbol = primitives.getBoxValueSymbol(tree.getType()); - Tree boxtree = gen.mkGlobalRef(tree.pos, symbol); - return tree.getType().equals(UNBOXED_UNIT) - ? gen.mkBlock(tree, gen.mkApply__(boxtree)) - : gen.mkApply_V(boxtree, new Tree[]{tree}); - } - - /** Unboxes the given tree to the given type. */ - private Tree unbox(Tree tree, Type pt) { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (primitives.getPrimitive(fun.symbol()) == Primitive.BOX) { - assert args.length == 1: tree; - return args[0]; - } - } - Symbol symbol = primitives.getUnboxValueSymbol(pt); - return gen.mkApply_V( - gen.mkGlobalRef(tree.pos, symbol), new Tree[]{tree}); - } - - /** Converts the given tree to the given type. */ - private Tree convert(Tree tree, Type to) { - Symbol symbol = primitives.getConvertSymbol(tree.type(), to); - return gen.mkApply_V( - gen.mkGlobalRef(tree.pos, symbol), new Tree[]{tree}); - } - - //######################################################################## - // Private Methods - Tree generation - - /** Generates given bridge method forwarding to given method. */ - private Tree genBridgeMethod(Symbol bridge, Symbol method) { - Type type = bridge.nextType(); - Tree body = genApply(bridge.pos, - gen.Select(gen.This(bridge.pos, bridge.owner()), method), - gen.mkLocalRefs(bridge.pos, type.valueParams())); - return gen.DefDef(bridge, coerce(body, type.resultType())); - } - - /** Generates an application with given function and arguments. */ - private Tree genApply(int pos, Tree fun, Tree[] args) { - switch (fun.getType()) { - case MethodType(Symbol[] params, Type result): - Tree[] args1 = args; - for (int i = 0; i < args.length; i++) { - Tree arg = args[i]; - Tree arg1 = coerce(arg, params[i].nextType()); - if (arg1 != arg && args1 == args) { - args1 = new Tree[args.length]; - for (int j = 0; j < i; j++) args1[j] = args[j]; - } - args1[i] = arg1; - } - return gen.mkApply_V(pos, fun, args1); - default: - throw Debug.abort("illegal type " + fun.getType() + " for " + fun); - } - } - - /** - * Generates a new unboxed array of given size and with elements - * of given type. - */ - private Tree genNewUnboxedArray(int pos, Type element, Tree size) { - if (global.target == global.TARGET_INT) { - Tree[] targs = {gen.mkType(pos, element)}; - Tree[] vargs = {coerce(size, UNBOXED_INT)}; - Tree fun = gen.mkGlobalRef(pos, primitives.NEW_OARRAY); - return gen.mkApplyTV(fun, targs, vargs); - } - switch (element) { - case UnboxedType(int kind): return genNewUnboxedArray(pos, kind, size); - } - String name = primitives.getNameForClassForName(element); - Tree[] args = { coerce(size, UNBOXED_INT), gen.mkStringLit(pos,name) }; - Tree array = - gen.mkApply_V(gen.mkGlobalRef(pos,primitives.NEW_OARRAY), args); - return gen.mkAsInstanceOf(array, Type.UnboxedArrayType(element)); - } - - /** - * Generates a new unboxed array of given size and with elements - * of given unboxed type kind. - */ - private Tree genNewUnboxedArray(int pos, int kind, Tree size) { - Symbol symbol = primitives.getNewArraySymbol(kind); - Tree[] args = { coerce(size, UNBOXED_INT) }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array length operation. */ - private Tree genUnboxedArrayLength(int pos, Tree array) { - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArrayLengthSymbol(array.getType()); - Tree[] args = { array }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array get operation. */ - private Tree genUnboxedArrayGet(int pos, Tree array, Tree index) { - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArrayGetSymbol(array.getType()); - index = coerce(index, UNBOXED_INT); - Tree[] args = { array, index }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array set operation. */ - private Tree genUnboxedArraySet(int pos, Tree array,Tree index,Tree value){ - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArraySetSymbol(array.getType()); - index = coerce(index, UNBOXED_INT); - value = coerce(value, getArrayElementType(array.getType())); - Tree[] args = { array, index, value }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - //######################################################################## - // Private Methods - Queries - - /** Returns the qualifier of the given tree. */ - private Tree getQualifier(Tree tree) { - switch (tree) { - case Select(Tree qualifier, _): - return qualifier; - default: - throw Debug.abort("no qualifier for tree", tree); - } - } - - /** Are the given erased types in a subtyping relation? */ - private boolean isSubType(Type tp1, Type tp2) { - global.nextPhase(); - boolean result = tp1.isSubType(tp2); - global.prevPhase(); - return result; - } - - /** Are the given erased types in an equality relation? */ - private boolean isSameAs(Type tp1, Type tp2) { - global.nextPhase(); - boolean result = tp1.isSameAs(tp2); - global.prevPhase(); - return result; - } - - /** Is the given type an unboxed type? */ - private boolean isUnboxedType(Type type) { - switch (type) { - case UnboxedType(_) : return true; - case UnboxedArrayType(_): return true; - default : return false; - } - } - - /** Is the given type an unboxed simple type? */ - private boolean isUnboxedSimpleType(Type type) { - switch (type) { - case UnboxedType(_) : return true; - default : return false; - } - } - - /** Is the given type an unboxed array type? */ - private boolean isUnboxedArrayType(Type type) { - switch (type) { - case UnboxedArrayType(_): return true; - default : return false; - } - } - - /** Returns the boxed version of the given unboxed type. */ - private Type boxUnboxedType(Type type) { - switch (type) { - case UnboxedType(TypeTags.UNIT): - return definitions.UNIT_CLASS.type(); - case UnboxedType(TypeTags.BOOLEAN): - return definitions.BOOLEAN_CLASS.type(); - case UnboxedType(TypeTags.BYTE): - return definitions.BYTE_CLASS.type(); - case UnboxedType(TypeTags.SHORT): - return definitions.SHORT_CLASS.type(); - case UnboxedType(TypeTags.CHAR): - return definitions.CHAR_CLASS.type(); - case UnboxedType(TypeTags.INT): - return definitions.INT_CLASS.type(); - case UnboxedType(TypeTags.LONG): - return definitions.LONG_CLASS.type(); - case UnboxedType(TypeTags.FLOAT): - return definitions.FLOAT_CLASS.type(); - case UnboxedType(TypeTags.DOUBLE): - return definitions.DOUBLE_CLASS.type(); - case UnboxedArrayType(Type element): - return Type.appliedType( - definitions.ARRAY_CLASS.type(), new Type[] {element}); - default: - throw Debug.abort("illegal case", type); - } - } - - /** Returns the element type of the given array type. */ - private Type getArrayElementType(Type type) { - switch (type) { - case TypeRef(_, Symbol symbol, Type[] args): - if (symbol != definitions.ARRAY_CLASS) break; - assert args.length == 1: type; - return args[0]; - case UnboxedArrayType(Type element): - return element; - } - throw Debug.abort("non-array type", type); - } - -////////////////////////////////////////////////////////////////////////////////// -// Bridge Building -///////////////////////////////////////////////////////////////////////////////// - - private TreeList bridges; - private HashMap bridgeSyms; - - /** Add bridge which Java-overrides `sym1' and which forwards to `sym' - */ - public void addBridge(Symbol owner, Symbol sym, Symbol sym1) { - Type bridgeType = sym1.nextType(); - - // create bridge symbol and add to bridgeSyms(sym) - // or return if bridge with required type already exists for sym. - SymSet bridgesOfSym = (SymSet) bridgeSyms.get(sym); - if (bridgesOfSym == null) bridgesOfSym = SymSet.EMPTY; - Symbol[] brs = bridgesOfSym.toArray(); - for (int i = 0; i < brs.length; i++) { - if (isSameAs(brs[i].type(), bridgeType)) return; - } - Symbol bridgeSym = sym.cloneSymbol(); - bridgeSym.flags |= (SYNTHETIC | BRIDGE); - bridgeSym.flags &= ~(JAVA | DEFERRED); - bridgesOfSym = bridgesOfSym.incl(bridgeSym); - bridgeSyms.put(sym, bridgesOfSym); - bridgeSym.setOwner(owner); - - // check that there is no overloaded symbol with same erasure as bridge - // todo: why only check for overloaded? - Symbol overSym = owner.members().lookup(sym.name); - switch (overSym.nextType()) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) { - if (sym != alts[i] && isSameAs(bridgeType, alttypes[i])) { - unit.error(sym.pos, "overlapping overloaded alternatives; " + - "overridden " + sym1 + sym1.locationString() + - " has same erasure as " + alts[i] + - alttypes[i] + alts[i].locationString()); - } - } - } - - switch (bridgeType) { - case MethodType(Symbol[] params, Type restp): - // assign to bridge symbol its bridge type - // where owner of all parameters is bridge symbol itself. - Symbol[] params1 = new Symbol[params.length]; - for (int i = 0; i < params.length; i++) { - params1[i] = params[i].cloneSymbol(bridgeSym); - } - bridgeSym.setType(Type.MethodType(params1, restp)); - - bridges.append(genBridgeMethod(bridgeSym, sym)); - } - - } - - /** Add an "empty bridge" (abstract method declaration) to satisfy - * CLR's requirement that classes should provide declaration - * for all methods of the interfaces they implement - */ - /* - public void addEmptyBridge(Symbol owner, Symbol method) { - Type bridgeType = method.nextType(); - Symbol bridgeSym = method.cloneSymbol(owner); - bridgeSym.flags = bridgeSym.flags & ~JAVA | SYNTHETIC | DEFERRED; - //bridgeSym.setOwner(owner); - switch (bridgeType) { - case MethodType(Symbol[] params, Type restp): - // assign to bridge symbol its bridge type - // where owner of all parameters is bridge symbol itself. - Symbol[] params1 = new Symbol[params.length]; - for (int i = 0; i < params.length; i++) { - params1[i] = params[i].cloneSymbol(bridgeSym); - } - bridgeSym.setType(Type.MethodType(params1, restp)); - Tree bridge = gen.DefDef(bridgeSym, Tree.Empty); - bridges.append(bridge); - } - } - */ - - private final Map interfaces/*<Symbol,Set<Symbol>>*/ = new HashMap(); - - private Set getInterfacesOf(Symbol clasz) { - assert clasz.isClass(): Debug.show(clasz); - Set set = (Set)interfaces.get(clasz); - if (set == null) { - set = new HashSet(); - interfaces.put(clasz, set); - Type parents[] = clasz.parents(); - for (int i = 0; i < parents.length; i++) - set.addAll(getInterfacesOf(parents[i].symbol())); - if (clasz.isInterface()) set.add(clasz); - } - return set; - } - - private void addInterfaceBridges_(Symbol clasz) { - assert clasz.isClass() && !clasz.isInterface(): Debug.show(clasz); - assert clasz.parents().length > 0: Debug.show(clasz)+": "+clasz.info(); - Symbol svper = clasz.parents()[0].symbol(); - assert svper.isClass() && !svper.isInterface(): Debug.show(clasz); - Set interfaces = new HashSet(getInterfacesOf(clasz)); - interfaces.removeAll(getInterfacesOf(svper)); - for (Iterator i = interfaces.iterator(); i.hasNext(); ) { - Symbol inter = (Symbol)i.next(); - addInterfaceBridgesAux(clasz, inter.members()); - } - } - - private void addInterfaceBridgesAux(Symbol owner, Scope symbols) { - for (Scope.SymbolIterator i = symbols.iterator(); - i.hasNext();) { - Symbol member = i.next(); - if (!member.isTerm() || !member.isDeferred()) continue; - addInterfaceBridges(owner, member); - } - } - - - private Symbol getOverriddenMethod(Symbol method) { - Type[] parents = method.owner().parents(); - if (parents.length == 0) return Symbol.NONE; - return method.overriddenSymbol(parents[0]); - } - - public void addBridgeMethodsTo(Symbol method) { - assert method.owner().isClass() && !method.owner().isInterface(); - Symbol overridden = getOverriddenMethod(method); - if (!overridden.isNone() && !isSameAs(overridden.nextType(), method.nextType())) - addBridge(method.owner(), method, overridden); - } - - public void addInterfaceBridges(Symbol owner, Symbol method) { - assert owner.isClass() && !owner.isInterface(): Debug.show(owner); - Symbol overriding = method.overridingSymbol(owner.thisType()); - if (overriding == method) { - Symbol overridden = method.overriddenSymbol(owner.thisType().parents()[0], owner); - if (!overridden.isNone() && !isSameAs(overridden.nextType(), method.nextType())) - addBridge(owner, method, overridden); - // moved this into the TypeCreator class of the MSIL backend - //if (forMSIL && (overridden.isNone() || overridden.owner() != owner)) - // addEmptyBridge(owner, method); - } else if (!overriding.isNone() && !isSameAs(overriding.nextType(), method.nextType())) - addBridge(owner, overriding, method); - } - - private void addBridges(Symbol clasz, TreeList members) { - TreeList savedBridges = bridges; - HashMap savedBridgeSyms = bridgeSyms; - bridges = new TreeList(); - bridgeSyms = new HashMap(); - - int length = members.length(); - if (!clasz.isInterface()) { - for (int i = 0; i < length; i++) { - switch (members.get(i)) { - case DefDef(_, _, _, _, _, Tree rhs): - addBridgeMethodsTo(members.get(i).symbol()); - } - } - addInterfaceBridges_(clasz); - } - - members.append(bridges); - if (bridges.length() > 0) { - Type info = clasz.nextInfo(); - switch (info) { - case CompoundType(Type[] parts, Scope members_): - members_ = members_.cloneScope(); - for (int i = 0; i < bridges.length(); i++) { - Tree bridge = (Tree)bridges.get(i); - members_.enterOrOverload(bridge.symbol()); - } - clasz.updateInfo(Type.compoundType(parts, members_, info.symbol())); - break; - default: - throw Debug.abort("class = " + Debug.show(clasz) + ", " + - "info = " + Debug.show(info)); - } - } - bridgeSyms = savedBridgeSyms; - bridges = savedBridges; - } - - -} diff --git a/sources/scalac/transformer/ErasurePhase.java b/sources/scalac/transformer/ErasurePhase.java deleted file mode 100644 index c0669e22f2..0000000000 --- a/sources/scalac/transformer/ErasurePhase.java +++ /dev/null @@ -1,135 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ErasurePhase.java,v 1.13 2002/11/14 15:58:22 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.backend.Primitive; -import scalac.backend.Primitives; -import scalac.symtab.Definitions; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Debug; - -public class ErasurePhase extends Phase { - - //######################################################################## - // Private Fields - - private final Definitions definitions; - private final Primitives primitives; - private final Erasure erasure; - - //######################################################################## - // Public Constructors - - public ErasurePhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - this.definitions = global.definitions; - this.primitives = global.primitives; - this.erasure = new Erasure(global); - } - - //######################################################################## - // Public Methods - - public void apply(CompilationUnit unit) { - erasure.apply(unit); - } - - public Type transformInfo(Symbol sym, Type tp) { - if (sym.isConstructor() && sym.constructorClass().isSubClass(definitions.ANYVAL_CLASS)) return tp; - if (sym.isClass()) { - if (sym == definitions.ANY_CLASS) return tp; - if (sym.isJava() && sym.isModuleClass()) return tp; - if (sym.isSubClass(definitions.ANYVAL_CLASS)) - if (sym != definitions.ANYVAL_CLASS) return tp; - switch (tp) { - case CompoundType(Type[] parents, Scope members): - assert parents.length != 0: Debug.show(sym) + " -- " + tp; - if (sym.isInterface()) { - Symbol superclass = parents[0].symbol(); - if (superclass.isJava() && !superclass.isInterface()) { - parents = Type.cloneArray(parents); - parents[0] = definitions.ANYREF_TYPE(); - tp = Type.compoundType(parents, members, sym); - } - } - return Type.erasureMap.map(tp); - default: - throw Debug.abort("illegal case", tp); - } - } - if (sym.isTerm() && sym.isParameter()) { - if (primitives.getPrimitive(sym.owner()) == Primitive.BOX) - return eraseUnboxMethodType(tp); - if (primitives.getPrimitive(sym.owner()) == Primitive.UNBOX) - return eraseBoxMethodType(tp); - } - if (sym.isType()) return tp; - if (sym.isThisSym()) return sym.owner().nextType(); - // if (sym == definitions.NULL) return tp.resultType().erasure(); - if (global.target == global.TARGET_INT && sym ==primitives.NEW_OARRAY){ - // !!! hack for interpreter - Name name = Name.fromString("element").toTypeName(); - Symbol tparam = sym.newTParam(sym.pos, 0, name, definitions.ANY_TYPE()); - return Type.PolyType(new Symbol[]{tparam}, tp); - } - switch (primitives.getPrimitive(sym)) { - case Primitive.IS : return Type.PolyType(tp.typeParams(), Type.MethodType(tp.valueParams(), tp.resultType().erasure())); - case Primitive.AS : return tp; - case Primitive.BOX: return eraseBoxMethodType(tp); - case Primitive.UNBOX: return eraseUnboxMethodType(tp); - default : return tp.erasure(); - } - } - - //######################################################################## - // Private Methods - - private Type eraseBoxMethodType(Type type) { - switch (type) { - case PolyType(_, Type result): - return eraseBoxMethodType(result); - case MethodType(Symbol[] params, Type result): - return Type.MethodType(params, eraseBoxMethodType(result)); - case TypeRef(Type prefix, Symbol clasz, Type[] args): - return Type.typeRef(prefix, clasz, Type.EMPTY_ARRAY); - default: - throw Debug.abort("illegal case", type); - } - } - - private Type eraseUnboxMethodType(Type type) { - switch (type) { - case PolyType(_, Type result): - return eraseUnboxMethodType(result); - case MethodType(Symbol[] params, Type result): - return Type.MethodType(params, eraseUnboxMethodType(result)); - case TypeRef(_, Symbol clasz, Type[] args): - if (clasz == definitions.ARRAY_CLASS) { - Symbol element = args[0].symbol(); - if (element.isAbstractType()) - if (element.info().symbol() == definitions.ANY_CLASS) - return definitions.ANYREF_CLASS.nextType(); - } - return type.fullErasure(); - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ExpandMixinsPhase.java b/sources/scalac/transformer/ExpandMixinsPhase.java deleted file mode 100644 index 969080039a..0000000000 --- a/sources/scalac/transformer/ExpandMixinsPhase.java +++ /dev/null @@ -1,473 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ExpandMixinsPhase.java,v 1.8 2002/05/02 10:59:35 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; -import java.util.LinkedList; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeGen; -import scalac.ast.TreeInfo; -import scalac.ast.TreeList; -import scalac.ast.Traverser; -import scalac.ast.Transformer; -import scalac.ast.GenTransformer; -import scalac.ast.GenTreeCloner; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -import scalac.util.Name; -import scalac.util.Names; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.SymbolCloner; -import scalac.symtab.SymbolSubstTypeMap; - -// TODO do not copy hidden members which are not accessible via -// "super". - -/** - * A phase to expand mixins using code copying. We assume that links - * to outer classes have been made explicit by a previous phase. - */ -// !!! needs to be cleaned -public class ExpandMixinsPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from classes to their interface */ - private final Map/*<Symbol,Symbol>*/ interfaces; - - /** A map from classes to their type transformer */ - private final Map/*<Symbol,TypeTransformer>*/ transformers; - - /** A map from classes to their expanded body */ - private final Map/*<Symbol,Tree[]>*/ expansions; - - /** A map from classes to their original (unexpanded) body */ - private final Map/*<Symbol,Tree[]>*/ bodies; - - /** A map from members to their original member */ - private final Map/*<Symbol,Symbol>*/ origins; - - - /** A transformer that expands classes that have mixins */ - private final GenTransformer expander; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ExpandMixinsPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - Phase addinterfaces = global.PHASE.ADDINTERFACES.phase(); - this.interfaces = ((AddInterfacesPhase)addinterfaces).classToIFace; - this.transformers = new HashMap(); - this.expansions = new HashMap(); - this.bodies = ((AddInterfacesPhase)addinterfaces).classToBody; - this.origins = new HashMap(); - this.expander = new TreeExpander(global); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - expander.apply(unit); - } - - /** Applies this phase to the given type for the given symbol. */ - public Type transformInfo(Symbol symbol, Type type) { - while (true) { - if (symbol.isJava()) return type; - if (symbol.isInterface()) return type; - if (symbol.isCompoundSym()) return type; // !!! check - if (symbol.isClass()) { - return getTypeExpander(symbol).apply(type); - } - symbol = symbol.isConstructor() - ? symbol.constructorClass() - : symbol.owner(); - } - } - - //######################################################################## - // Private Methods - - //######################################################################## - // Private Class - Tree expander - - /** - * A tree transformer that expands class definitions and removes - * compiled units. - */ - private class TreeExpander extends GenTransformer { - public TreeExpander(Global global) { - super(global); - } - public void apply(CompilationUnit unit) { - if (unit.mixinOnly) { - assert Debug.log("removing unit " + unit); - unit.body = Tree.EMPTY_ARRAY; - } else { - super.apply(unit); - } - } - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - Symbol clasz = tree.symbol(); - if (clasz.isInterface()) return super.transform(tree); - return gen.ClassDef(clasz, getExpandedBody(clasz)); - default: - return super.transform(tree); - } - } - } - - //######################################################################## - // Private Class - Tree inliner - - /** - * A Tree cloner that clones mixin bodies. It assumes that these - * bodies have already been expanded. References to mixin value - * parameters are replaced by references to newly-created inlined - * fields. The symbol of Super and This nodes is replaced by the - * symbol of the generated class. The symbol of super members is - * rebound if required. Note that as the input tree has already - * been expanded, it contains only super member to the first - * supertype of the mixin, all other super members have been - * removed during the expansion of the input tree. - */ - private static class TreeInliner extends GenTreeCloner { - private final Symbol clasz; - private final Type supertype; - private boolean initializer; - public TreeInliner(Global global, TypeTransformer transformer) { - super(global, transformer, transformer.cloner); - // !!! global.nextPhase(); - this.clasz = transformer.clasz; - // !!! global.prevPhase(); - this.supertype = clasz.nextInfo().parents()[0]; - } - public Symbol getSymbolFor(Tree tree) { - switch (tree) { - case Select(Super(_, _), _): - if (tree.symbol().isInitializer()) return tree.symbol(); // !!! - assert supertype.symbol().isSubClass(tree.symbol().owner()): - tree + " -- " + Debug.show(clasz); - global.nextPhase(); - Symbol symbol = tree.symbol().overriddenSymbol(supertype); - assert !symbol.isNone(): Debug.show(tree, clasz, supertype); - global.prevPhase(); - return symbol; - case Super(_, _): - case This(_): - return clasz; - default: - return super.getSymbolFor(tree); - } - } - public Tree transform(Tree tree) { - switch (tree) { - case ValDef(_, _, _, _): - if (tree.symbol().hasStaticAttribute()) - return Tree.Empty; - break; - case DefDef(_, _, _, _, _, _): - Symbol symbol = getSymbolFor(tree); - if (symbol.owner() != clasz || symbol.hasStaticAttribute()) - return Tree.Empty; - if (symbol.isInitializer()) initializer = true; - tree = super.transform(tree); - initializer = false; - return tree; - case Apply(Select(Super(_, _), _), _): - if (TreeInfo.methSymbol(tree).isInitializer() && !initializer) - return Tree.Empty; - break; - } - if (tree.hasSymbol() && tree.symbol().isParameter()) { - Symbol symbol = getSymbolFor(tree); - if (!symbol.isParameter()) { - assert tree instanceof Tree.Ident: tree; - return gen.Select(gen.This(tree.pos, clasz), symbol); - } - } - return super.transform(tree); - } - } - - //######################################################################## - // Private Class - Class tree expander - - /** - * A tree transformer that expands a class definitions. Super - * members are rebound and/or rewritten into normal members. - */ - private class ClassTreeExpander extends TreeExpander { - private final Symbol clasz; - private final Type[] parents; - private final Map clones; - public ClassTreeExpander(Global global, TypeTransformer transformer) { - super(global); - this.clasz = transformer.clasz; - this.parents = clasz.parents(); - this.clones = transformer.cloner.clones; - } - private Symbol getSuperMember(Symbol member) { - for (int i = 0; i < parents.length; i++) { - global.nextPhase(); - if (!parents[i].symbol().isSubClass(member.owner())) { - global.prevPhase(); // !!! - continue; - } - Symbol override = member.overridingSymbol(parents[i]); - global.prevPhase(); - assert !override.isNone(): - Debug.show(member, clasz, parents[i]); - if (i == 0) return override; - Symbol clone = (Symbol)clones.get(override); - assert clone != null: Debug.show(member, override, clasz); - return clone; - } - // !!! double loop - for (int i = 0; i < parents.length; i++) { - if (!parents[i].symbol().isSubClass(member.owner())) continue; - //global.nextPhase(); - Symbol override = member.overridingSymbol(parents[i]); - //global.prevPhase(); - assert !override.isNone(): - Debug.show(member, clasz, parents[i]); - if (i == 0) return override; - Symbol clone = (Symbol)clones.get(override); - assert clone != null: Debug.show(member, override, clasz); - return clone; - } - throw Debug.abort(Debug.show(member, clasz)); - } - public Tree transform(Tree tree) { - switch (tree) { - case Select(Super(_, _), _): - Symbol symbol = getSuperMember(tree.symbol()); - Tree qualifier = symbol.owner() == clasz - ? gen.This(tree.pos, clasz) - : gen.Super(tree.pos, clasz); - return gen.Select(tree.pos, qualifier, symbol); - default: - return super.transform(tree); - } - } - } - - - - - - - - - - - - - - - - /** Returns the type transformer to use for the given class. */ - private TypeTransformer getTypeExpander(Symbol clasz) { // !!! - assert clasz.isClass() && !clasz.isInterface(): Debug.show(clasz); - TypeTransformer transformer =(TypeTransformer)transformers.get(clasz); - if (transformer == null) { - transformer = new TypeTransformer(clasz); - transformers.put(clasz, transformer); - } - return transformer; - } - - /** Returns the expanded body of the given clasz. */ - private Tree[] getExpandedBody(Symbol clasz) { - Tree[] body = (Tree[])expansions.get(clasz); - if (body == null) { - body = (Tree[])bodies.remove(clasz); - assert body != null: Debug.show(clasz); - TypeTransformer transformer = getTypeExpander(clasz); - TreeList list = new TreeList(); - assert Debug.log("expanding tree ", clasz); - Type[] parents = clasz.parents(); - TreeInliner inliner = new TreeInliner(global, transformer); - for (int i = 1; i < parents.length; i++) { - Symbol mixin = parents[i].symbol(); - if (mixin.isInterface()) continue; - assert Debug.log("expanding tree ", clasz, ": inlining ", mixin); - list.append(inliner.transform(getExpandedBody(mixin))); - } - ClassTreeExpander expander = new ClassTreeExpander(global, transformer); - list.append(expander.transform(body)); - body = list.toArray(); - expansions.put(clasz, body); - } - return body; - } - - //######################################################################## - // Private Class - Collector - - private class TypeTransformer extends Type.MapOnlyTypes { - - public final Symbol clasz; - public final Type[] parents; - public final SymbolCloner cloner; - public final Map/*<Symbol,Type>*/ inlines; - - public TypeTransformer(Symbol clasz) { - this.clasz = clasz; - this.parents = clasz.parents(); - this.cloner = new SymbolCloner(); - this.inlines = new HashMap(); - initialize(); - } - - private void initialize() { - Type[] parents = clasz.parents(); - // !!! parents.length > 0 - if (parents.length > 0) parents[0].symbol().nextInfo(); // force - assert Debug.log("expanding type ", clasz); - for (int i = parents.length - 1; 0 < i; i--) { - switch (parents[i]) { - case TypeRef(Type prefix, Symbol mixin, Type[] args): - if (mixin.isInterface()) continue; - mixin.nextInfo(); // force - assert Debug.log("expanding type ", clasz, ": inlining ", mixin); - cloner.owners.put(mixin, clasz); - cloner.owners.put(mixin.primaryConstructor(), clasz); - // map mixin type parameters to mixin type arguments - Symbol[] tparams = mixin.typeParams(); - for (int j = 0; j < tparams.length; j++) - inlines.put(tparams[j], args[j]); - - createMixedInMemberSymbols(mixin.nextInfo().members()); - } - } - Set clones = new HashSet(cloner.clones.keySet()); -// cloner.clones.putAll(getTypeTransformerFor(parents[0].symbol()).cloner.clones); // !!! build closure - - // !!! remove ? - for (Iterator i = cloner.clones.values().iterator(); i.hasNext();){ - // !!! for (Iterator i = clones.iterator(); i.hasNext();){ - Symbol clone = (Symbol)i.next(); - clone.setInfo(apply(clone.info())); - } - } - - private Symbol getMemberOrigin(Symbol member) { - Object origin = origins.get(member); - return origin == null ? member : (Symbol)origin; - } - - private void createMixedInMemberSymbols(Scope symbols) { - Scope scope = clasz.members(); - for (SymbolIterator i = symbols.iterator(); i.hasNext();) { - Symbol member = i.next(); - boolean shadowed = member.isPrivate() || member.isInitializer() - || member.overridingSymbol(clasz.thisType()) != member; - Symbol origin = getMemberOrigin(member); - if (!shadowed && origin != null) { - Symbol overridden = member.overriddenSymbol(parents[0]); - if (origin == getMemberOrigin(overridden)) { - cloner.clones.put(member, overridden); - continue; - } - } - // !!! when the symbol is shadowed, inlining could be - // avoided if the original definition is accessible - // through super - assert Debug.log("expanding type ", clasz, ": cloning ", member); - Symbol clone = cloner.cloneSymbol(member); - if (shadowed) clone.name = Names.MIXIN(member); - if (shadowed) clone.flags &= ~Modifiers.OVERRIDE; - if (shadowed) clone.flags &= ~Modifiers.ACCESSFLAGS; - if (shadowed) clone.flags |= Modifiers.PRIVATE; - scope.enterOrOverload(clone); - origins.put(clone, origin != null ? origin : member); - } - } - - - public Type apply(Type type) { - switch (type) { - case TypeRef(Type prefix, Symbol symbol, Type[] args): - Type inline = (Type)inlines.get(symbol); - if (inline != null) return inline; - if (symbol.isParameter()) { - Symbol clone = (Symbol)cloner.clones.get(symbol); - if (clone != null) { - assert prefix == Type.NoPrefix && args.length == 0: - type; - return Type.typeRef(prefix, clone, args); - } - } - return map(type); - case SingleType(Type prefix, Symbol symbol): - Symbol clone = (Symbol)cloner.clones.get(symbol); - prefix = apply(prefix); - return Type.singleType(prefix, clone != null ? clone : symbol); - case ThisType(_): - return clasz.thisType(); - case CompoundType(Type[] parents, Scope members): - if (type.symbol() != clasz) return map(type); - if (parents.length <= 1) return type; - Symbol iface = (Symbol)interfaces.get(clasz); - if (iface == null) { - int i = 1; - while (i < parents.length && parents[i].symbol().isInterface()) i++; - if (i == parents.length) return type; - parents = Type.cloneArray(parents); - while (i < parents.length) { - if (!parents[i].symbol().isInterface()) - parents[i] = Type.typeRef(parents[i].prefix(), (Symbol)interfaces.get(parents[i].symbol()), parents[i].typeArgs()); - i++; - } - return Type.compoundType(parents, members, clasz); - } - assert parents[parents.length - 1].symbol() == iface: type; - if (parents.length == 2) return type; - for (int i = 1; i < parents.length - 1; i++) { - Symbol mixin = parents[i].symbol(); - Symbol imix = mixin.isInterface() - ? mixin - : (Symbol)interfaces.get(mixin); - assert iface.isSubClass(imix): type+" - "+i; - } - parents = new Type[] {parents[0], parents[parents.length - 1]}; - return Type.compoundType(parents, members, clasz); - default: - return map(type); - } - } - - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ExplicitOuterClassesPhase.java b/sources/scalac/transformer/ExplicitOuterClassesPhase.java deleted file mode 100644 index b1b05832a1..0000000000 --- a/sources/scalac/transformer/ExplicitOuterClassesPhase.java +++ /dev/null @@ -1,558 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.util.Collections; -import java.util.Map; -import java.util.HashMap; -import java.util.Iterator; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; - -/** - * This phase does the following: - * - * - In every nested class, adds to each of its constructor a new - * value parameter that contains a link to the outer class. - * - * - In every nested type, adds to each of its constructor a new type - * parameter for every type parameter appearing in outer types. - * - * - In every class, adds a forwarding "super" method for every method - * that is accessed via "super" in a nested class. - * - * - Replaces all prefixes of TypeRefs by localThisTypes. - * - * - Adds all missing qualifiers. - */ -// !!! needs to be cleaned -public class ExplicitOuterClassesPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from constructor symbols to type transformers */ - private final Map/*<Symbol,TypeTransformer>*/ transformers = new HashMap(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ExplicitOuterClassesPhase(Global global,PhaseDescriptor descriptor){ - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - /** Applies this phase to the given type for the given symbol. */ - public Type transformInfo(Symbol symbol, Type type) { - if (symbol.isConstructor()) { - Symbol clasz = symbol.constructorClass(); - if (clasz.isClass() && !clasz.isCompoundSym()) - return transformInfo(clasz, symbol, type); - } - return getTypeTransformerFor(symbol).apply(type); - } - - //######################################################################## - // Private Methods - - /** - * Computes and returns the new type of the constructor. As a side - * effect, creates and stores the type transformer corresponding - * to this constructor. - */ - private Type transformInfo(Symbol clasz, Symbol constructor, Type type) { - Symbol[] tparams = type.typeParams(); - Symbol[] vparams = type.valueParams(); - int depth = getClassDepth(clasz); - - Map/*<Symbol,Type>*/ table = new HashMap(); - table.put(clasz, clasz.thisType()); - for (int i = 0; i < tparams.length; i++) - table.put(tparams[i], tparams[i].type()); - - Symbol[] owners = new Symbol[depth]; - Symbol[][] tparamss = new Symbol[depth][]; - - Symbol vlink = null; - if (depth > 0) { - int count = depth; - Symbol owner = clasz.owner(); - for (int i = depth - 1; i >= 0; i--) { - owners[i] = owner; - tparamss[i] = owner.typeParams(); - count += tparamss[i].length; - owner = owner.owner(); - } - - // create outer value link - vparams = Symbol.cloneArray(1, vparams); - int vflags = Modifiers.SYNTHETIC; - Name vname = Names.OUTER(constructor); - vlink = constructor.newVParam(constructor.pos, vflags, vname); - vlink.setInfo(clasz.owner().thisType()); - vparams[0] = vlink; - - int o = 0; - tparams = Symbol.cloneArray(count, tparams); - for (int i = 0; i < depth; i++) { - // create new type parameters - for (int j = 0; j < tparamss[i].length; j++) { - Symbol oldtparam = tparamss[i][j]; - Symbol newtparam = oldtparam.cloneSymbol(constructor); - newtparam.name = Names.OUTER(constructor, oldtparam); - table.put(oldtparam, newtparam.type()); - tparams[o++] = newtparam; - } - // create outer type links - int tflags = Modifiers.PARAM | Modifiers.COVARIANT | Modifiers.SYNTHETIC | Modifiers.STABLE; - Name tname = Names.OUTER(constructor, owners[i]); - Symbol tlink = constructor.newTParam( - constructor.pos, tflags, tname, owners[i].typeOfThis()); - table.put(owners[i], tlink.type()); - tparams[o++] = tlink; - } - - } - - transformers.put(constructor, new TypeTransformer(table)); - type = Type.typeRef(Type.NoPrefix, clasz, Symbol.type(tparams)); - type = Type.MethodType(vparams, type); - if (tparams.length > 0) type = Type.PolyType(tparams, type); - return type; - } - - /** Returns the type transformer for the given symbol. */ - private TypeTransformer getTypeTransformerFor(Symbol symbol) { - while (true) { - Symbol test = symbol; - if (test.isConstructor()) test = test.constructorClass(); - // !!! isClassType -> isClass ? - if (test.isClassType() && !test.isCompoundSym()) break; - symbol = symbol.owner(); - } -// !!! -// while (!symbol.isClassType() && !(symbol.isConstructor() && symbol.constructorClass().isClassType())) // !!! isClassType -> isClass ? -// symbol = symbol.owner(); - if (symbol.isClassType()) - symbol = symbol.primaryConstructor(); - if (symbol.constructorClass().isPackageClass()) - return topLevelTypeTransformer; - TypeTransformer context = (TypeTransformer)transformers.get(symbol); - if (context == null) { - symbol.nextInfo(); - context = (TypeTransformer)transformers.get(symbol); - assert context != null: Debug.show(symbol); - } - return context; - } - - //######################################################################## - // Private Functions - - /** - * Returns the depth of the specified class. The depth of a class - * is: - * - -1 for a package class - * - 0 for a top-level class - * - the depth of the enclosing class plus 1 for an inner class - */ - private static int getClassDepth(Symbol clasz) { - assert clasz.isClass() || clasz.isPackageClass(): Debug.show(clasz); - int depth = -1; - while (!clasz.isPackageClass()) { clasz = clasz.owner(); depth++; } - return depth; - } - - /** - * Returns the type arguments of the flattened version of the - * specified type reference. This functions takes and returns - * non-transformed types. - */ - private static Type[] getFlatArgs(Type prefix, Symbol clasz, Type[] args) { - int depth = getClassDepth(clasz); - if (depth <= 0) return args; - Type[] prefixes = new Type[depth]; - Type[][] argss = new Type[depth][]; - int count = collect(prefix, clasz, prefixes, argss); - args = Type.cloneArray(count, args); - for (int i = 0, o = 0; i < depth; i++) { - for (int j = 0; j < argss[i].length; j++) - args[o++] = argss[i][j]; - args[o++] = prefixes[i]; - } - return args; - } - // where - private static int collect(Type prefix, Symbol clasz, Type[] prefixes, - Type[][] argss) - { - int count = prefixes.length; - for (int i = prefixes.length - 1; i >= 0; i--) { - prefixes[i] = prefix; - Symbol owner = clasz.owner(); - Type base = prefix.baseType(owner); - switch (base) { - case TypeRef(Type type, Symbol symbol, Type[] args): - assert symbol == owner: Debug.show(base); - count += args.length; - argss[i] = args; - prefix = type; - clasz = owner; - continue; - default: - throw Debug.abortIllegalCase(base); - } - } - return count; - } - - //######################################################################## - // Private Class - Type transformer - - /** The type transformer for top-level types */ - private static final TypeTransformer topLevelTypeTransformer = - new TypeTransformer(Collections.EMPTY_MAP); - - /** The type transformer */ - private static final class TypeTransformer extends Type.MapOnlyTypes { - - private final Map/*<Symbol,Type>*/ tparams; - - public TypeTransformer(Map tparams) { - this.tparams = tparams; - } - - public Type apply(Type type) { - switch (type) { - case TypeRef(Type prefix, Symbol symbol, Type[] args): - if (symbol.isParameter() && symbol.owner().isConstructor()) { - assert prefix == Type.NoPrefix: type; - assert args.length == 0: type; - Object value = tparams.get(symbol); - return value != null ? (Type)value : type; - } - if (symbol.isClass() && !symbol.isCompoundSym()) { - args = map(getFlatArgs(prefix, symbol, args)); - prefix = Type.NoPrefix; - return Type.typeRef(prefix, symbol, args); - } - if (symbol.isPackageClass()) { - args = Type.EMPTY_ARRAY; - prefix = Type.NoPrefix; - return Type.typeRef(prefix, symbol, args); - } - return Type.typeRef(apply(prefix), symbol, map(args)); - case SingleType(Type prefix, Symbol symbol): - if (symbol.owner().isPackageClass()) - return Type.singleType(Type.NoPrefix, symbol); - return Type.singleType(apply(prefix), symbol); - case ThisType(Symbol clasz): - Object value = tparams.get(clasz); - if (value != null) return (Type)value; - assert clasz.isCompoundSym() || clasz.isPackageClass(): - Debug.show(clasz); - return type; - case CompoundType(Type[] parents, Scope members): - // !!! this case should not be needed - return Type.compoundType(map(parents), members, type.symbol()); - default: - return map(type); - } - } - - } - - //######################################################################## - // Private Class - Tree transformer - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - /** The current context */ - private Context context; - - /** The current method */ - private Symbol method; - - /** Transforms the given type. */ - public Type transform(Type type) { - return context.transformer.apply(type); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - if (global.debug) global.log("transforming " + tree);//debug - switch (tree) { - - case ClassDef(_, _, _, _, _, Template impl): - Symbol clasz = tree.symbol(); - context = new Context(context, clasz, new HashMap(), new HashMap()); - Tree[] parents = transform(impl.parents); - Tree[] body = transform(impl.body); - body = Tree.concat(body, genAccessMethods(false)); - body = Tree.concat(body, genAccessMethods(true)); - if (context.vfield != null) { - body = Tree.cloneArray(1, body); - body[0] = gen.ValDef( - context.vfield, - gen.Ident(context.vfield.pos, context.vparam)); - } - context = context.outer; - return gen.ClassDef(clasz, parents, impl.symbol(), body); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol method = tree.symbol(); - Context backup = context; - if (method.isConstructor()) - context = context.getConstructorContext(method); - this.method = method; - rhs = transform(rhs); - this.method = null; - context = backup; - return gen.DefDef(method, rhs); - - case Apply(Tree vfun, Tree[] vargs): - switch (vfun) { - case TypeApply(Tree tfun, Tree[] targs): - if (!tfun.symbol().isConstructor()) break; - return transform(tree, vargs, vfun, targs, tfun); - default: - if (!vfun.symbol().isConstructor()) break; - return transform(tree, vargs, vfun, Tree.EMPTY_ARRAY,vfun); - } - return super.transform(tree); - - case This(_): - return genOuterRef(tree.pos, tree.symbol()); - - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - if (symbol.owner().isStaticOwner()) // !!! qualifier ignored - return gen.mkGlobalRef(tree.pos, symbol); - Symbol access; - switch (qualifier) { - case Super(_, _): - Symbol clasz = qualifier.symbol(); - if (clasz == context.clasz) { - access = symbol; - qualifier = gen.Super(tree.pos, qualifier.symbol()); - } else { - access = getAccessSymbol(symbol, clasz); - qualifier = genOuterRef(qualifier.pos, clasz); - } - break; - default: - access = getAccessSymbol(symbol, null); - qualifier = transform(qualifier); - break; - } - tree = gen.Select(tree.pos, qualifier, access); - if (access != symbol && !symbol.isMethod()) - tree = gen.mkApply__(tree); - return tree; - - default: - return super.transform(tree); - } - } - - /* Add outer type and value arguments to constructor calls. */ - private Tree transform(Tree vapply, Tree[] vargs, Tree tapply, - Tree[] targs, Tree tree) - { - switch (tree) { - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - Symbol clasz = symbol.constructorClass(); - if (getClassDepth(clasz) > 0) { - Type[] types = Tree.typeOf(targs); - types = getFlatArgs(qualifier.type(), clasz, types); - targs = gen.mkTypes(tapply.pos, types); - vargs = Tree.cloneArray(1, vargs); - vargs[0] = qualifier; - } else { - assert !containsValue(qualifier): tree; - } - tree = gen.Ident(tree.pos, symbol); - if (targs.length != 0) - tree = gen.TypeApply(tapply.pos, tree, transform(targs)); - return gen.Apply(vapply.pos, tree, transform(vargs)); - default: - throw Debug.abortIllegalCase(tree); - } - } - - /** - * Returns the symbol to access the specified member from the - * current context. If "svper" is non null, the member is - * selected from the superclass of the specified class. The - * returned symbol may be the same as the given one. - */ - private Symbol getAccessSymbol(Symbol member, Symbol svper) { - if (member.isPublic() && svper == null) return member; - Context context = this.context; - for (; context != null; context = context.outer) - if (svper != null - ? context.clasz == svper - : member.isPrivate() - ? context.clasz == member.owner() - // !!! This is incorrect without static access methods - : context.clasz.isSubClass(member.owner())) break; - assert context != null: Debug.show(this.context, member); - if (context == this.context) return member; - Map table = svper != null ? context.supers : context.selfs; - Symbol access = (Symbol)table.get(member); - if (access == null) { - // !!! generate static access methods ? - Name name = Names.ACCESS(member, svper != null); - access = context.clasz.newAccessMethod(context.clasz.pos,name); - global.nextPhase(); - Type info = member.isMethod() - ? member.info().cloneType(member, access) - : Type.MethodType(Symbol.EMPTY_ARRAY, member.info()); - access.setInfo(info); - global.prevPhase(); - table.put(member, access); - context.clasz.nextInfo().members().enter(access); - assert Debug.log("created access method: ", access); - } - return access; - } - - /** Generates the trees of the access methods. */ - private Tree[] genAccessMethods(boolean withSuper) { - Map table = withSuper ? context.supers : context.selfs; - if (table.size() == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[table.size()]; - Iterator entries = table.entrySet().iterator(); - for (int i = 0; i < trees.length; i++) { - Map.Entry entry = (Map.Entry)entries.next(); - Symbol member = (Symbol)entry.getKey(); - Symbol access = (Symbol)entry.getValue(); - int pos = access.pos; - Tree qualifier = withSuper - ? gen.Super(pos, context.clasz) - : gen.This(pos, context.clasz); - Tree select = gen.Select(qualifier, member); - Tree[] targs = gen.mkTypeRefs(pos, access.nextTypeParams()); - Tree[] vargs = gen.mkLocalRefs(pos, access.nextValueParams()); - Tree body = member.isMethod() - ? gen.mkApplyTV(select, targs, vargs) - : select; - trees[i] = gen.DefDef(access, body); - } - return trees; - } - - /** Returns a tree referencing the given outer class. */ - private Tree genOuterRef(int pos, Symbol clasz) { - if (context.clasz == clasz) return gen.This(pos, clasz); - Tree tree = method == null || method.isConstructor() - ? gen.Ident(pos, context.vparam) - : gen.Select(gen.This(pos, context.clasz),context.getVField()); - for (Context c = context.outer;; c = c.outer) { - assert c != null: Debug.show(clasz, context.clasz); - if (c.clasz == clasz) return tree; - Symbol access = getAccessSymbol(c.getVField(), null); - tree = gen.Apply(gen.Select(tree, access)); - } - } - - /** Tests whether the tree contains some value computation. */ - private boolean containsValue(Tree tree) { - switch (tree) { - case This(_): - return !tree.symbol().isPackageClass(); - case Select(Tree qualifier, _): - return containsValue(qualifier) || tree.symbol().isValue(); - default: - return false; - } - } - - }; - - //######################################################################## - // Private Class - Tree transformer context - - /** This class represents the tree transformation context. */ - private class Context { - - /** The outer context */ - public final Context outer; - /** The context class */ - public final Symbol clasz; - /** The context type transformer */ - public final TypeTransformer transformer; - /** The self access methods (maps members to accessors) */ - public final Map/*<Symbol,Symbol>*/ selfs; - /** The super access methods (maps members to accessors) */ - public final Map/*<Symbol,Symbol>*/ supers; - /** The context outer paramater (null if none) */ - public final Symbol vparam; - /** The context outer field (null if none or not yet used) */ - private Symbol vfield; - - /** Initializes this instance. */ - public Context(Context outer, Symbol symbol, Map selfs, Map supers) { - this.outer = outer; - this.clasz = symbol.constructorClass(); - this.transformer = getTypeTransformerFor(symbol); - this.selfs = selfs; - this.supers = supers; - this.vparam = outer != null ? symbol.nextValueParams()[0] : null; - } - - /** Returns a context for the given constructor. */ - public Context getConstructorContext(Symbol constructor) { - assert constructor.constructorClass() == clasz; - return new Context(outer, constructor, selfs, supers); - } - - /** - * Returns the outer value field. The field is created on the - * fly if it does not yet exist. - */ - private Symbol getVField() { - assert outer != null: Debug.show(clasz); - if (vfield == null) { - int flags = - Modifiers.SYNTHETIC | Modifiers.PRIVATE | Modifiers.STABLE; - vfield = clasz.newField(clasz.pos, flags, Names.OUTER(clasz)); - vfield.setInfo(outer.clasz.thisType()); - clasz.members().enterNoHide(vfield); - } - return vfield; - } - - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ICodePhase.java b/sources/scalac/transformer/ICodePhase.java deleted file mode 100644 index 3274897641..0000000000 --- a/sources/scalac/transformer/ICodePhase.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import ch.epfl.lamp.util.CodePrinter; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; - -/** - * This class represents the ICode phase for the java version - * of the compiler. It doesn't do anything but permit to make - * a bridge between the java implementation of Socos et the - * scala one. See scala.tools.scalac.icode.ICodePhase for - * implementation - */ -public abstract class ICodePhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ICodePhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Prints the given compilation units. */ - public abstract void print(CompilationUnit[] units, CodePrinter printer); - - //######################################################################## -} diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java deleted file mode 100644 index fdf14e8d9b..0000000000 --- a/sources/scalac/transformer/LambdaLift.java +++ /dev/null @@ -1,763 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.io.*; -import java.util.HashMap; - -import scalac.*; -import scalac.ast.*; -import scalac.symtab.*; -import scalac.util.*; -import Tree.*; - - -/** A lambda lifting transformer - * - * @author Martin Odersky - * @version 1.0 - * - * What it does: - * Lift every class and function that's contained in another function - * out to be a member to the next enclosing class. - * Pass free variables and type variables as parameters to class constructors. - * Variables and values that are free in some function or class - * are given new unique names. - * Free mutable variables are converted to reference cells. - * All types are updated so that proxies are passed for additional free - * type variables. - */ -public class LambdaLift extends OwnerTransformer - implements Modifiers, Kinds { - - final Global global; - final Definitions definitions; - final FreeVars free; - final LambdaLiftPhase descr; - private CompilationUnit unit; - - public LambdaLift(Global global, LambdaLiftPhase descr) { - super(global); - this.global = global; - this.definitions = global.definitions; - this.free = new FreeVars(global); - this.descr = descr; - } - - public void apply(CompilationUnit unit) { - this.unit = unit; - global.log(unit.source.toString()); - free.initialize(unit); - currentOwner = global.definitions.ROOT_CLASS; - unit.body = transformTemplateStats(unit.body, currentOwner); - } - - /** If `sym' is a class, return its primary constructor; - * otherwise current symbol itself - * - * @param sym - * @return - */ - static Symbol asFunction(Symbol sym) { - return sym.kind == CLASS ? sym.primaryConstructor() : sym; - } - - /** Is symbol local relative to owner? - * Primary constructor parameters are local iff owner (contained in) - * the primary constructor. - * - * @param sym - * @param owner - * @return <code>true</code> if the symbol <code>sym</code> - * is local relative to <code>owner</code> - */ - static boolean isLocal(Symbol sym, Symbol owner) { - if (sym.isParameter() && - sym.owner().isPrimaryConstructor() && - sym.owner().constructorClass().kind == CLASS && - !(owner.isParameter() && owner.owner() == sym)) { - Symbol encl = sym.owner().owner(); - Symbol clazz = sym.owner().constructorClass(); - //System.out.println("isLocal " + sym + " " + encl + " " + clazz + " " + owner);//DEBUG - while (owner != encl && - owner.kind != NONE && - owner != clazz) { - owner = owner.owner(); - //System.out.println(":" + owner);//DEBUG - } - return owner != clazz; - } - return sym.isLocal(); - } - - /** Propagate free variables from all called functions. - * `asFunction' applied to the next enclosing function or class owner. - * - * @param owner - * @return - */ - static Symbol enclFun(Symbol owner) { - Symbol sym = owner; - while (!asFunction(sym).isMethod()) sym = sym.owner(); - return asFunction(sym); - } - - /** Return SymSet from a hashmap. - * - * @param f - * @param sym - * @return - */ - private static SymSet get(HashMap f, Symbol sym) { - SymSet ss = (SymSet) f.get(sym); - return ss == null ? SymSet.EMPTY : ss; - } - - /** Compute free variables map `fvs'. - * Also assign unique names to all - * value/variable/let symbols that are free in some function or class, and to - * all class/function symbols that are owned by some function. - */ - static class FreeVars extends OwnerTransformer { - - private CompilationUnit unit; - - public FreeVars(Global global) { - super(global); - } - - /** A hashtable storing free variables of functions and class constructors. - */ - private HashMap/*<Symbol,SymSet>*/ fvs; - - /** A hashtable storing free type variables of functions and class constructors. - */ - private HashMap/*<Symbol,SymSet>*/ ftvs; - - /** A hashtable storing calls between functions and class constructors - */ - private HashMap/*<Symbol,SymSet>*/ called; - - /** The set of symbols that need to be renamed. - */ - private SymSet renamable; - - /** The set of symbols that bound by polytypes - * and therefore are not free type variables. - */ - private SymSet excluded; - - /** A flag to indicate whether new free variables have been found - */ - private boolean changedFreeVars; - - /** A flag to indicate whether we are in propagation phase - * (used in assertion). - */ - private boolean propagatePhase; - - /** Insert `sym' into the set of free variables of `owner' - * - * @param owner - * @param sym - */ - private void putFree(Symbol owner, Symbol sym) { - assert owner.isLocal(); - HashMap f = sym.isType() ? ftvs : fvs; - SymSet ss = get(f, owner); - if (!ss.contains(sym)) { - f.put(owner, ss.incl(sym)); - changedFreeVars = true; - if (global.debug) global.log(sym + " is free in " + owner); - } - } - - /** Insert `to' into the set of functions called by `from' - * - * @param from - * @param to - */ - private void putCall(Symbol from, Symbol to) { - SymSet ss = get(called, from); - if (!ss.contains(to)) { - called.put(from, ss.incl(to)); - } - } - - /** Mark symbol `sym' as being free in `owner', unless `sym' - * is defined in `owner' or there is a class between `owner's owner - * and the owner of `sym'. - * Return `true' if there is no class between `owner' and - * the owner of sym. - * - * @param sym - * @param owner - * @return - */ - private boolean markFree(Symbol sym, Symbol owner) { - if (global.debug) - global.log("mark " + sym + " of " + sym.owner() + - " free in " + owner);//debug - if (owner.kind == NONE) { - assert propagatePhase : sym + " in " + sym.owner(); - return false; - } else if (sym.owner() == owner) { - return true; - } else if (markFree(sym, owner.owner())) { - Symbol fowner = asFunction(owner); - if (fowner.isMethod()) { - putFree(fowner, sym); - renamable = renamable.incl(sym); - if (sym.isVariable()) sym.flags |= CAPTURED; - } - return owner.kind != CLASS; - } else { - return false; - } - } - - /** Assign unique name to symbol. - * If symbol is a class assign same name to its primary constructor. - */ - private void makeUnique(Symbol sym) { - sym.name = unit.fresh.newName(sym.name); - } - - private Type.Map traverseTypeMap = new Type.Map() { - public Type apply(Type tp) { - if (global.debug) global.log("traverse " + tp);//debug - switch (tp) { - case TypeRef(NoPrefix, Symbol sym, Type[] targs): - if (isLocal(sym, currentOwner) && - sym.kind == TYPE && - !excluded.contains(sym)) - markFree(sym, currentOwner); - break; - case SingleType(NoPrefix, Symbol sym): - if (isLocal(sym, currentOwner)) - markFree(sym, currentOwner); - break; - case PolyType(Symbol[] tparams, Type restp): - for (int i = 0; i < tparams.length; i++) - excluded = excluded.incl(tparams[i]); - Type tp1 = super.map(tp); - for (int i = 0; i < tparams.length; i++) - excluded = excluded.excl(tparams[i]); - return tp1; - } - return map(tp); - } - }; - - public Tree transform(Tree tree) { - if (global.debug) global.log("free " + tree);//debug - assert tree.type != null : tree; - traverseTypeMap.apply(tree.type.widen()); - Symbol sym = tree.symbol(); - switch(tree) { - case ClassDef(_, _, _, _, _, _): - case DefDef(_, _, _, _, _, _): - if (sym.isLocal()) { - renamable = renamable.incl(sym); - } - return super.transform(tree); - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AbsTypeDef( - tree, sym, - transform(rhs, currentOwner), - transform(lobound, currentOwner)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AliasTypeDef( - tree, sym, - transform(tparams, currentOwner), - transform(rhs, currentOwner)); - - case Ident(_): - if (isLocal(sym, currentOwner)) { - if (sym.isMethod()) { - Symbol f = enclFun(currentOwner); - if (f.name.length() > 0) // it is not a template function { - putCall(f, sym); - } else if (sym.kind == VAL || sym.kind == TYPE) { - markFree(sym, currentOwner); - } - } - return tree; - - default: - return super.transform(tree); - } - } - - /** Propagate free fariables from all called functions. - * - * @param fvs - */ - void propagateFvs(HashMap fvs) { - Object[] fs = called.keySet().toArray(); - for (int i = 0; i < fs.length; i++) { - Symbol f = (Symbol) fs[i]; - Symbol[] calledFromF = get(called, f).toArray(); - for (int j = 0; j < calledFromF.length; j++) { - //System.out.println(f + " calls " + calledFromF[j]);//DEBUG - Symbol[] newFvs = get(fvs, calledFromF[j]).toArray(); - for (int k = 0; k < newFvs.length; k++) { - markFree(newFvs[k], f); - } - } - } - } - - /** This method re-enters all free variables into their free variable - * sets. This is necessary because the names of these variables (and - * therefore their `isLess' order have changed. - * - * @param fvs - */ - private void restoreFvs(HashMap fvs) { - Object[] fs = fvs.keySet().toArray(); - for (int i = 0; i < fs.length; i++) { - Symbol f = (Symbol) fs[i]; - Symbol[] elems = get(fvs, f).toArray(); - SymSet elems1 = SymSet.EMPTY; - for (int j = 0; j < elems.length; j++) - elems1 = elems1.incl(elems[j]); - fvs.put(f, elems1); - } - } - - /** Compute a mapping from symbols to their free variables - * in hashtable `fvs'. Also rename all variables that need it. - * - * @param unit - */ - public void initialize(CompilationUnit unit) { - this.unit = unit; - fvs = new HashMap(); - ftvs = new HashMap(); - called = new HashMap(); - renamable = SymSet.EMPTY; - excluded = SymSet.EMPTY; - apply(unit); - - propagatePhase = true; - do { - changedFreeVars = false; - propagateFvs(fvs); - propagateFvs(ftvs); - } while (changedFreeVars); - - Symbol[] ss = renamable.toArray(); - for (int i = 0; i < ss.length; i++) { - makeUnique(ss[i]); - } - - restoreFvs(fvs); - restoreFvs(ftvs); - } - } - - private TreeList liftedDefs; - - /** Transform template and add lifted definitions to it. - * - * @param stats - * @param tsym - * @return - */ - public Tree[] transformTemplateStats(Tree[] stats, Symbol tsym) { - TreeList prevLiftedDefs = liftedDefs; - liftedDefs = new TreeList(); - TreeList stats1 = new TreeList(super.transformTemplateStats(stats, tsym)); - stats1.append(liftedDefs); - liftedDefs = prevLiftedDefs; - return stats1.toArray(); - } - - /** ... - * - * @param tree - */ - public Tree transform(Tree tree) { - //global.debugPrinter.print("lifting ").print(tree).println().end();//DEBUG - //System.out.print(tree.type + " --> ");//DEBUG - tree.type = descr.transform(tree.type, currentOwner); - //System.out.println(tree.type);//DEBUG - switch (tree) { - case Block(Tree[] stats, Tree value): - for (int i = 0; i < stats.length; i++) - liftSymbol(stats[i]); - return copy.Block(tree, transform(stats), transform(value)); - - case ClassDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): - Symbol sym = tree.symbol(); - if ((mods & LIFTED) != 0) { - ((ClassDef) tree).mods &= ~LIFTED; - Tree tree1 = copy.ClassDef( - tree, sym, - addTypeParams(transform(tparams, sym), newtparams(sym.primaryConstructor())), - new ValDef[][]{ - addParams(transform(vparams, sym)[0], newparams(sym.primaryConstructor()))}, - transform(tpe, sym), - transform(impl, sym)); - liftedDefs.append(tree1); - return Tree.Empty; - } else { - assert !sym.isLocal() : sym; - return copy.ClassDef( - tree, sym, - transform(tparams, sym), - transform(vparams, sym), - transform(tpe, sym), - transform(impl, sym)); - } - - case DefDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): - Symbol sym = tree.symbol(); - if ((mods & LIFTED) != 0) { - ((DefDef) tree).mods &= ~LIFTED; - Tree tree1 = copy.DefDef( - tree, sym, - addTypeParams(transform(tparams, sym), newtparams(sym)), - new ValDef[][]{ - addParams(transform(vparams, sym)[0], newparams(sym))}, - transform(tpe, sym), - transform(rhs, sym)); - liftedDefs.append(tree1); - return Tree.Empty; - } else { - assert !sym.isLocal() : sym; - return copy.DefDef( - tree, sym, - transform(tparams, sym), transform(vparams, sym), transform(tpe, sym), - transform(rhs, sym)); - } - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AbsTypeDef( - tree, tree.symbol(), - transform(rhs, currentOwner), - transform(lobound, currentOwner)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AliasTypeDef( - tree, tree.symbol(), - transform(tparams, currentOwner), - transform(rhs, currentOwner)); - - case ValDef(_, _, _, Tree rhs): - Symbol sym = tree.symbol(); - rhs = transform(rhs, sym); - if (sym.isCaptured()) { - assert sym.isLocal(); - switch (sym.nextType()) { - case TypeRef(_, Symbol clasz, Type[] args): - Tree constr = gen.mkPrimaryConstructorGlobalRef(rhs.pos, clasz); - rhs = gen.New(gen.mkApplyTV(constr, args, new Tree[]{rhs})); - break; - default: - throw Debug.abort("illegal case", sym.nextType()); - } - } - return gen.ValDef(sym, rhs); - - case Sequence(Tree[] args): - throw new ApplicationError("this should not happen"); - /* // moved this to Uncurry - Tree tree1 = gen.mkNewList(tree.pos, tree.type.typeArgs()[0], transform(args)); - //System.out.println("TUPLE: " + tree + "\n ==> \n" + tree1);//DEBUG - return tree1; - */ - - case Return(Block(Tree[] stats, Tree value)): - return transform( - gen.Block(stats, gen.Return(tree.pos, tree.symbol(), value))); - - case Return(Tree expr): - if (tree.symbol() != currentOwner.enclMethod()) { - unit.error(tree.pos, "non-local return not yet implemented"); - } - return super.transform(tree); - - case Apply(Tree fn, Tree[] args): - Symbol fsym = TreeInfo.methSymbol(fn); - Tree fn1 = transform(fn); - switch (fn1) { - case TypeApply(Tree fn2, Tree[] targs): - //if (args.length == 1 && fn2.symbol() == definitions.PREDEF_ARRAY()) { - // throw new ApplicationError("this should not happen"); - /* // this moved to UnCurry - switch (args[0]) { - case Sequence(Tree[] items): - assert targs.length == 1: tree; - Tree array = gen.mkNewArray( - args[0].pos, - targs[0].type(), - transform(items), - currentOwner); - // fn2 may be like "{ println("hello"); Predef}.Array" - switch (fn2) { - case Select(Tree qualifier, _): - return gen.mkBlock(args[0].pos, qualifier, array); - default: - throw Debug.abort("illegal case", fn2); - } - } - */ - //} - fn1 = copy.TypeApply( - fn1, fn2, addFreeArgs(tree.pos, get(free.ftvs, fsym), targs, true)); - break; - default: - Tree[] targs = addFreeArgs( - tree.pos, get(free.ftvs, fsym), Tree.EMPTY_ARRAY, true); - if (targs.length > 0) - fn1 = gen.TypeApply(fn1, targs); - } - Tree[] args1 = transform(args); - return copy.Apply( - tree, fn1, addFreeArgs(tree.pos, get(free.fvs, fsym), args1, false)); - - case Ident(_): - Symbol sym = tree.symbol(); - if (isLocal(sym, currentOwner) && - (sym.kind == TYPE || (sym.kind == VAL && !sym.isMethod()))) { - sym = descr.proxy(sym, currentOwner); - } - Tree tree1 = gen.mkLocalRef(tree.pos, sym); - if (sym.isCaptured()) - return gen.Select(tree1, definitions.REF_ELEM()); - else - return tree1; - - default: - return super.transform(tree); - } - } - - private Symbol[] ftvsParams(Symbol owner) { - Symbol[] freevars = get(free.ftvs, owner).toArray(); - Symbol[] params = new Symbol[freevars.length]; - for (int i = 0; i < params.length; i++) { - params[i] = freevars[i].cloneSymbol(owner); - params[i].pos = owner.pos; - params[i].flags = PARAM | SYNTHETIC; - } - for (int i = 0; i < params.length; i++) - params[i].setInfo(freevars[i].info().subst(freevars, params)); - return params; - } - - private Symbol[] fvsParams(Symbol owner) { - Symbol[] freevars = get(free.fvs, owner).toArray(); - Symbol[] params = new Symbol[freevars.length]; - for (int i = 0; i < params.length; i++) { - params[i] = freevars[i].cloneSymbol(owner); - params[i].pos = owner.pos; - params[i].flags &= CAPTURED; - params[i].flags |= PARAM | SYNTHETIC; - params[i].setInfo(freevars[i].type()); - } - return params; - } - - private Symbol[] newtparams(Symbol owner) { - Symbol[] tparams = owner.nextType().typeParams(); - int nfree = get(free.ftvs, owner).size(); - assert nfree == tparams.length - owner.type().typeParams().length - : owner + " " + nfree + " " + tparams.length + " " + owner.type().firstParams().length; - Symbol[] newtparams = new Symbol[nfree]; - System.arraycopy(tparams, tparams.length - nfree, newtparams, 0, nfree); - return newtparams; - } - - private Symbol[] newparams(Symbol owner) { - Symbol[] params = owner.nextType().firstParams(); - int nfree = get(free.fvs, owner).size(); - assert nfree == params.length - owner.type().firstParams().length; - Symbol[] newparams = new Symbol[nfree]; - System.arraycopy(params, params.length - nfree, newparams, 0, nfree); - return newparams; - } - - /** For members: - * change symbol of tree so that - * owner = currentClass - * newparams are added - * enter symbol in scope of currentClass - * For non-members: - * change symbol of tree so that - * owner = currentMember - */ - private void liftSymbol(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - ((ClassDef) tree).mods |= LIFTED; - Symbol sym = tree.symbol(); - sym.flags |= LIFTED; - assert sym.isLocal() : sym; - Symbol constr = sym.primaryConstructor(); - liftSymbol( - sym, get(free.ftvs, constr).toArray(), - ftvsParams(constr), fvsParams(constr)); - break; - - case DefDef(_, _, _, _, _, _): - ((DefDef) tree).mods |= LIFTED; - Symbol sym = tree.symbol(); - sym.flags |= LIFTED | PRIVATE; - assert sym.isLocal() : sym; - liftSymbol( - sym, get(free.ftvs, sym).toArray(), - ftvsParams(sym), fvsParams(sym)); - break; - - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol sym = tree.symbol(); - assert sym.isLocal() : sym; - // This is to fix the owner of y from x to f in this example: - // class C { def f = { val x = { val y = ...; y } } } - if (!isClassMember(sym.owner())) { - assert isClassMember(sym.owner().owner()): Debug.show(tree, sym); - sym.setOwner(sym.owner().owner()); - } - break; - - } - } - // where - private boolean isClassMember(Symbol sym) { - return sym.isConstructor() || sym.owner().isClass(); - } - - private void liftSymbol(Symbol sym, Symbol[] oldtparams, - Symbol[] newtparams, Symbol[] newparams) { - Symbol enclClass = sym.owner(); - while (!enclClass.isClassType()) { - enclClass = enclClass.isConstructor() && !enclClass.isPrimaryConstructor() - ? enclClass.constructorClass() - : enclClass.owner(); - } - if (!sym.isConstructor()) sym.setOwner(enclClass); - if (!sym.isConstructor()) enclClass.members().enter(sym); - if (sym.isMethod()) { - if (newtparams.length != 0 || newparams.length != 0) { - sym.updateInfo( - addParams( - addTypeParams( - sym.nextInfo(), oldtparams, newtparams), - newparams)); - if (global.debug) - global.log(sym + " has now type " + sym.nextType()); - } - } else if (sym.kind == CLASS) { - Symbol constr = sym.primaryConstructor(); - liftSymbol(constr, oldtparams, newtparams, newparams); - // fix result type of constructor - constr.updateInfo(descr.transform(constr.nextInfo(), constr)); - } else { - throw new ApplicationError(); - } - } - - private Type addTypeParams(Type tp, Symbol[] oldtparams, Symbol[] newtparams) { - if (newtparams.length == 0) return tp; - switch (tp) { - case MethodType(_, _): - return Type.PolyType( - newtparams, - Type.getSubst(oldtparams, newtparams, true).apply(tp)); - case PolyType(Symbol[] tparams, Type restpe): - Symbol[] tparams1 = new Symbol[tparams.length + newtparams.length]; - System.arraycopy(tparams, 0, tparams1, 0, tparams.length); - System.arraycopy(newtparams, 0, tparams1, tparams.length, newtparams.length); - return Type.PolyType( - tparams1, - Type.getSubst(oldtparams, newtparams, true).apply(restpe)); - default: - throw new ApplicationError("illegal type: " + tp); - } - } - - private Type addParams(Type tp, Symbol[] newparams) { - if (newparams.length == 0) return tp; - switch (tp) { - case MethodType(Symbol[] params, Type restpe): - Symbol[] params1 = new Symbol[params.length + newparams.length]; - System.arraycopy(params, 0, params1, 0, params.length); - System.arraycopy(newparams, 0, params1, params.length, newparams.length); - return Type.MethodType(params1, restpe); - case PolyType(Symbol[] tparams, Type restpe): - return Type.PolyType(tparams, addParams(restpe, newparams)); - default: - throw new ApplicationError("illegal type: " + tp); - } - } - - private AbsTypeDef[] addTypeParams(AbsTypeDef[] tparams, Symbol[] newtparams) { - if (newtparams.length == 0) return tparams; - AbsTypeDef[] tparams1 = new AbsTypeDef[tparams.length + newtparams.length]; - System.arraycopy(tparams, 0, tparams1, 0, tparams.length); - for (int i = 0; i < newtparams.length; i++) { - tparams1[tparams.length + i] = gen.mkTypeParam(newtparams[i]); - } - return tparams1; - } - - private ValDef[] addParams(ValDef[] params, Symbol[] newparams) { - if (newparams.length == 0) return params; - ValDef[] params1 = new ValDef[params.length + newparams.length]; - System.arraycopy(params, 0, params1, 0, params.length); - for (int i = 0; i < newparams.length; i++) { - params1[params.length + i] = gen.mkParam(newparams[i]); - } - return params1; - } - - /** For all variables or type variables in `fvs', - * append proxies to argument array `args'. - * - * @param pos - * @param fvs - * @param args - * @param types - * @return - */ - private Tree[] addFreeArgs(int pos, SymSet fvs, Tree[] args, boolean types) { - if (fvs != SymSet.EMPTY) { - Symbol[] fparams = fvs.toArray(); - Tree[] args1 = new Tree[args.length + fparams.length]; - System.arraycopy(args, 0, args1, 0, args.length); - for (int i = 0; i < fparams.length; i++) { - Symbol farg = descr.proxy(fparams[i], currentOwner); - args1[args.length + i] = - types ? gen.mkTypeRef(pos, farg) : gen.Ident(pos, farg); - } - return args1; - } else { - return args; - } - } - -} diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java deleted file mode 100644 index 06c1984249..0000000000 --- a/sources/scalac/transformer/LambdaLiftPhase.java +++ /dev/null @@ -1,175 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -//import java.util.ArrayList; - -import scalac.*; -import scalac.parser.*; -import scalac.symtab.*; -import scalac.util.ArrayApply; - - -public class LambdaLiftPhase extends Phase implements Kinds, Modifiers { - - /** Initializes this instance. */ - public LambdaLiftPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - /** Applies this phase to the given compilation unit. - * - * @param unit - */ - public void apply(CompilationUnit unit) { - new LambdaLift(global, this).apply(unit); - } - - /** ... - * - * @param sym - * @param tp - * @return - */ - public Type transformInfo(Symbol sym, Type tp) { - /* - if (global.debug) - global.log("transform info for " + sym + ":" + tp + sym.locationString()); - */ - Type tp1 = tp; - if (sym != Symbol.NONE) { - switch (tp) { - case MethodType(_, _): - case PolyType(_, _): - tp1 = transform(tp, sym); - break; - default: - if (sym.kind == CLASS) - tp1 = transform(tp, sym); - else - tp1 = transform(tp, sym.owner()); - } - } - if (sym.isCaptured()) - return global.definitions.REF_TYPE(tp1); - else return tp1; - } - - /** Add proxies as type arguments for propagated type parameters. - * - * @param tp - * @param owner - * @return - */ - Type transform(Type tp, Symbol owner) { - return transformTypeMap.setOwner(owner).apply(tp); - } - - /** MapOnlyTypes => All symbols are mapped to themselves. - */ - private class TransformTypeMap extends Type.MapOnlyTypes { - Symbol owner; -// ArrayList/*<Symbol>*/ excluded = new ArrayList(); - Type.Map setOwner(Symbol owner) { this.owner = owner; return this; } - - public Type apply(Type tp) { - switch (tp) { - case TypeRef(Type pre, Symbol sym, Type[] targs): - if (sym.kind == CLASS) { - switch (pre) { - case NoPrefix: - pre = sym.owner().enclClass().thisType(); - tp = Type.typeRef(pre, sym, targs); - } - } - switch (pre) { - case NoPrefix: - if (LambdaLift.isLocal(sym, owner)) { - assert targs.length == 0; - return proxy(sym, owner).type(); - } - break; - case ThisType(_): - if (sym.kind == CLASS && - sym.primaryConstructor().isUpdatedAt(LambdaLiftPhase.this)) { - Symbol[] tparams = sym.primaryConstructor().nextInfo().typeParams(); - int i = tparams.length; - while (i > 0 && tparams[i-1].isSynthetic()) - i--; - if (i < tparams.length) { - if (global.debug) - global.log("adding proxies for " + sym + - ": " + ArrayApply.toString(tparams)); - - Type[] targs1 = new Type[tparams.length]; - System.arraycopy(map(targs), 0, targs1, 0, targs.length); - while (i < tparams.length) { - targs1[i] = proxy(tparams[i], owner).type(); - i++; - } - return Type.typeRef(pre, sym, targs1); - } - } - } - break; -/* - case PolyType(Symbol[] tparams, _): - if (tparams.length != 0) { - int len = excluded.size(); - for (int i = 0; i < tparams.length; i++) - excluded.add(tparams[i]); - Type tp1 = map(tp); - for (int i = 0; i < tparams.length; i++) - excluded.remove(excluded.size() - 1); - return tp1; - } -*/ - } - return map(tp); - } - } - - private TransformTypeMap transformTypeMap = new TransformTypeMap(); - - /** Return closest enclosing (type)parameter that has same name as `fv', - * or `fv' itself if this is the closest definition. - * - * @param fv - * @param owner - * @return - */ - Symbol proxy(Symbol fv, Symbol owner) { - if (global.debug) - global.log("proxy " + fv + " of " + fv.owner() + - " in " + LambdaLift.enclFun(owner)); - Symbol o = owner; - while (o.kind != NONE) { - if (global.debug) - global.log("looking in " + LambdaLift.enclFun(o) + " " + - ArrayApply.toString(o.typeParams())); - Symbol fowner = LambdaLift.enclFun(o); - if (fowner.isMethod()) { - if (LambdaLift.enclFun(fv.owner()) == fowner) return fv; - Type ft = (fowner.isUpdatedAt(this)) ? fowner.nextType() - : fowner.type(); - Symbol[] ownerparams = fv.isType() ? ft.typeParams() - : ft.firstParams(); - for (int i = 0; i < ownerparams.length; i++) { - if (ownerparams[i].name == fv.name) - return ownerparams[i]; - } - } - assert o.owner() != o; - o = o.owner(); - } - return fv; - //throw new ApplicationError("proxy " + fv + " in " + owner); - } - -} diff --git a/sources/scalac/transformer/MakeBoxingExplicitPhase.java b/sources/scalac/transformer/MakeBoxingExplicitPhase.java deleted file mode 100644 index 435886b1dc..0000000000 --- a/sources/scalac/transformer/MakeBoxingExplicitPhase.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.checkers.TreeChecker; -import scalac.symtab.Definitions; - -/** - * This phase makes boxing and unboxing of primitive values and arrays - * explicit. - */ -public class MakeBoxingExplicitPhase extends Phase { - - //######################################################################## - // Private Fields - - private final Definitions definitions; - private final TreeChecker checker; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public MakeBoxingExplicitPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - this.definitions = global.definitions; - this.checker = new TreeChecker(definitions); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - assert checker.check(unit); - new scalac.atree.ATreeFromSTree(definitions).translate(unit); // !!! - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/OwnerTransformer.java b/sources/scalac/transformer/OwnerTransformer.java deleted file mode 100644 index 55ee93dadd..0000000000 --- a/sources/scalac/transformer/OwnerTransformer.java +++ /dev/null @@ -1,189 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.*; -import scalac.ast.*; -import scalac.symtab.Kinds; -import scalac.symtab.Symbol; -import scalac.util.Name; -import Tree.*; - - -/** A default transformer class which also maintains owner information - * - * @author Martin Odersky - * @version 1.0 - */ -public class OwnerTransformer extends Transformer { - - protected Symbol currentOwner; - - public OwnerTransformer(Global global) { - super(global); - } - - public void apply(CompilationUnit unit) { - currentOwner = global.definitions.ROOT_CLASS; - unit.body = transform(unit.body); - } - - /** .. - * - * @param tree - * @param owner - * @return - */ - public Tree transform(Tree tree, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - Tree tree1 = transform(tree); - currentOwner = prevOwner; - return tree1; - } - - /** .. - * - * @param params - * @param owner - * @return - */ - public AbsTypeDef[] transform(AbsTypeDef[] params, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - AbsTypeDef[] res = transform(params); - currentOwner = prevOwner; - return res; - } - - /** .. - * - * @param params - * @param owner - * @return - */ - public ValDef[][] transform(ValDef[][] params, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - ValDef[][] res = transform(params); - currentOwner = prevOwner; - return res; - } - - /** .. - * - * @param templ - * @param owner - * @return - */ - public Template transform(Template templ, Symbol owner) { - Symbol prevOwner = currentOwner; - if (owner.kind == Kinds.CLASS) - currentOwner = owner.primaryConstructor(); - Tree[] parents1 = transform(templ.parents); - currentOwner = owner; - Tree[] body1 = transformTemplateStats(templ.body, templ.symbol()); - currentOwner = prevOwner; - return copy.Template(templ, parents1, body1); - } - - /** .. - * - * @param ts - * @param tsym - * @return - */ - public Tree[] transformTemplateStats(Tree[] ts, Symbol tsym) { - Tree[] ts1 = ts; - for (int i = 0; i < ts.length; i++) { - Tree t = transformTemplateStat(ts[i], tsym); - if (t != ts[i] && ts1 == ts) { - ts1 = new Tree[ts.length]; - System.arraycopy(ts, 0, ts1, 0, i); - } - ts1[i] = t; - } - return ts1; - } - - /** .. - * - * @param stat - * @param tsym - * @return - */ - public Tree transformTemplateStat(Tree stat, Symbol tsym) { - return transform(stat, tsym); - } - - /** .. - * - * @param tree - * @return - */ - public Tree transform(Tree tree) { - switch(tree) { - case PackageDef(Tree packaged, Template impl): - return copy.PackageDef( - tree, - transform(packaged), - transform(impl, packaged.symbol())); - - case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): - Symbol symbol = tree.symbol(); - return copy.ClassDef( - tree, symbol, - transform(tparams, symbol.primaryConstructor()), - transform(vparams, symbol.primaryConstructor()), - transform(tpe, symbol), - transform(impl, symbol)); - - case ModuleDef(_, _, Tree tpe, Template impl): - Symbol symbol = tree.symbol(); - return copy.ModuleDef( - tree, symbol, - transform(tpe, symbol), - transform(impl, symbol.moduleClass())); - - case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.DefDef( - tree, symbol, - transform(tparams, symbol), - transform(vparams, symbol), - transform(tpe, symbol), - transform(rhs, symbol)); - - case ValDef(_, _, Tree tpe, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.ValDef( - tree, symbol, - transform(tpe), - transform(rhs, symbol)); - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - Symbol symbol = tree.symbol(); - return copy.AbsTypeDef( - tree, symbol, - transform(rhs, symbol), - transform(lobound, symbol)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.AliasTypeDef( - tree, symbol, - transform(tparams, symbol), - transform(rhs, symbol)); - - default: - return super.transform(tree); - } - } - -} diff --git a/sources/scalac/transformer/TailCallPhase.java b/sources/scalac/transformer/TailCallPhase.java deleted file mode 100644 index 4798e22c1a..0000000000 --- a/sources/scalac/transformer/TailCallPhase.java +++ /dev/null @@ -1,296 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.GenTransformer; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * A Tail Call Transformer - * - * @author Erik Stenman - * @version 1.0 - * - * What it does: - * - * Finds method calls in tail-position and replaces them with jumps. - * A call is in a tail-position if it is the last instruction to be - * executed in the body of a method. This is done by recursing over - * the trees that may contain calls in tail-position (trees that can't - * contain such calls are not transformed). However, they are not that - * many. - * - * Self-recursive calls in tail-position are replaced by jumps to a - * label at the beginning of the method. As the JVM provides no way to - * jump from a method to another one, non-recursive calls in - * tail-position are not optimized. - * - * A method call is self-recursive if it calls the current method on - * the current instance and the method is final (otherwise, it could - * be a call to an overridden method in a subclass). Furthermore, If - * the method has type parameters, the call must contain these - * parameters as type arguments. - * - * Nested functions can be tail recursive (if this phase runs before - * lambda lift) and they are transformed as well. - * - * If a method contains self-recursive calls, a label is added to at - * the beginning of its body and the calls are replaced by jumps to - * that label. - */ -public class TailCallPhase extends Phase { - - private static class Context { - /** The current method */ - public Symbol method = Symbol.NONE; - - /** The current tail-call label */ - public Symbol label = Symbol.NONE; - - /** The expected type arguments of self-recursive calls */ - public Type[] types; - - /** Tells whether we are in a tail position. */ - public boolean tailPosition; - - public Context() { - this.tailPosition = false; - } - - /** - * The Context of this transformation. It contains the current enclosing method, - * the label and the type parameters of the enclosing method, together with a - * flag which says whether our position in the tree allows tail calls. This is - * modified only in <code>Block</code>, where stats cannot possibly contain tail - * calls, but the value can. - */ - public Context(Symbol method, Symbol label, Type[] types, boolean tailPosition) { - this.method = method; - this.label = label; - this.types = types; - this.tailPosition = tailPosition; - } - } - - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public TailCallPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - //######################################################################## - // Private Classes - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - - /** The context of this call */ - private Context ctx = new Context(); - - /** Transform the given tree, which is (or not) in tail position */ - public Tree transform(Tree tree, boolean tailPos) { - boolean oldTP = ctx.tailPosition; - ctx.tailPosition = tailPos; - tree = transform(tree); - ctx.tailPosition = oldTP; - return tree; - } - - public Tree[] transform(Tree[] trees, boolean tailPos) { - boolean oldTP = ctx.tailPosition; - ctx.tailPosition = tailPos; - trees = transform(trees); - ctx.tailPosition = oldTP; - return trees; - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - - case DefDef(_, _, _, _, _, Tree rhs): - Context oldCtx = ctx; - - ctx = new Context(); - - //assert method == null: Debug.show(method) + " -- " + tree; - ctx.method = tree.symbol(); - ctx.tailPosition = true; - - if (ctx.method.isMethodFinal() || ctx.method.owner().isMethod()) { - ctx.label = ctx.method.newLabel(ctx.method.pos, ctx.method.name); - ctx.types = Type.EMPTY_ARRAY; - Type type = ctx.method.type(); - switch (type) { - case PolyType(Symbol[] tparams, Type result): - ctx.types = Symbol.type(tparams); - type = result; - } - ctx.label.setInfo(type.cloneType(ctx.method, ctx.label)); - rhs = transform(rhs); - if (ctx.label.isAccessed()) { - global.log("Rewriting def " + ctx.method.simpleName()); - rhs = gen.LabelDef(ctx.label, ctx.method.valueParams(), rhs); - } - tree = gen.DefDef(ctx.method, rhs); - } else { - assert !ctx.method.isMethodFinal() - : "Final method: " + ctx.method.simpleName(); - // non-final method - ctx.tailPosition = false; - tree = gen.DefDef(tree.symbol(), transform(rhs)); - } - ctx = oldCtx; - return tree; - - case Block(Tree[] stats, Tree value): - boolean oldPosition = ctx.tailPosition; - ctx.tailPosition = false; stats = transform(stats); - ctx.tailPosition = oldPosition; - return gen.Block(tree.pos, stats, transform(value)); - - - case If(Tree cond, Tree thenp, Tree elsep): - Type type = tree.type(); - thenp = transform(thenp); - elsep = transform(elsep); - return gen.If(tree.pos, cond, thenp, elsep); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - Type type = tree.type(); - bodies = transform(bodies); - otherwise = transform(otherwise); - return gen.Switch(tree.pos, test, tags, bodies,otherwise,type); - - // handle pattern matches explicitly - case Apply(Select(_, scalac.util.Names._match), Tree[] args): - Tree newTree = global.make.Apply(tree.pos, ((Tree.Apply)tree).fun, transform(args)); - newTree.setType(tree.getType()); - return newTree; - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - if (ctx.method != Symbol.NONE && ctx.tailPosition) { - assert targs != null : "Null type arguments " + tree; - assert ctx.types != null : "Null types " + tree; - - if (!Type.isSameAs(Tree.typeOf(targs), ctx.types) | - !ctx.tailPosition) - return tree; - return transform(tree, fun, transform(vargs, false)); - } else - return tree; - - case Apply(Tree fun, Tree[] vargs): - if (ctx.tailPosition) - return transform(tree, fun, transform(vargs, false)); - else - return gen.mkApply_V(fun, transform(vargs, false)); - - case Visitor(Tree.CaseDef[] cases): - Tree newTree = global.make.Visitor(tree.pos, super.transform(cases)); - newTree.setType(tree.getType()); - return newTree; - - case CaseDef(Tree pattern, Tree guard, Tree body): - return gen.CaseDef(pattern, guard, transform(body)); - - case Typed(Tree expr, Tree type): - return gen.Typed(transform(expr), type); - - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol impl_symbol = getSymbolFor(impl); - Tree[] body = transform(impl.body); - return gen.ClassDef(getSymbolFor(tree), impl.parents, impl_symbol, body); - - case PackageDef(_, _): - case LabelDef(_, _, _): - case Return(_): - return super.transform(tree); - - - case Empty: - case ValDef(_, _, _, _): - case Assign(_, _): - case New(_): - case Super(_, _): - case This(_): - case Select(_, _): - case Ident(_): - case Literal(_): - case TypeTerm(): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case Import(_, _): - case Function(_, _): - return tree; - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Transforms the given function call. */ - private Tree transform(Tree tree, Tree fun, Tree[] vargs) { - if (fun.symbol() != ctx.method) - return tree; - switch (fun) { - case Select(Tree qual, _): - if (!isReferenceToThis(qual, ctx.method.owner())) - return tree; - global.log("Applying tail call recursion elimination for " + - ctx.method.enclClass().simpleName() + "." + ctx.method.simpleName()); - return gen.Apply(tree.pos, gen.Ident(qual.pos, ctx.label), vargs); - - case Ident(_): - global.log("Applying tail call recursion elimination for function " + - ctx.method.enclClass().simpleName() + "." + ctx.method.simpleName()); - return gen.Apply(tree.pos, gen.Ident(fun.pos, ctx.label), vargs); - - default: - throw Debug.abort("illegal case", fun); - } - } - - /** - * Returns true if the tree represents the current instance of - * given class. - */ - private boolean isReferenceToThis(Tree tree, Symbol clasz) { - switch (tree) { - case This(_): - assert tree.symbol() == clasz: tree +" -- "+ Debug.show(clasz); - return true; - default: - return false; - } - } - - }; - - //######################################################################## -} diff --git a/sources/scalac/transformer/TypesAsValuesPhase.java b/sources/scalac/transformer/TypesAsValuesPhase.java deleted file mode 100644 index 394373bd94..0000000000 --- a/sources/scalac/transformer/TypesAsValuesPhase.java +++ /dev/null @@ -1,1415 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.symtab.Definitions; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.symtab.Modifiers; -import scalac.atree.AConstant; -import scalac.ast.Transformer; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.TreeGen; -import scalac.ast.TreeList; -import scalac.backend.Primitives; - -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -import java.util.Map; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Arrays; -import java.util.Collections; - -/** - * Turn types into values by applying the following transformations: - * - * - For all type member T of all classes, add an accessor method - * T$type returnining the type as a value (the accessor is abstract - * if the type member is abstract). - * - * - For all polymorphic methods/constructors, add a value parameter - * for each type parameter. - * - * - Add a method getScalaType to every class, to obtain its type as a - * value. - * - * - Transform all type expressions into value expressions: type - * application is turned into value application, type selection into - * value selection, and so on. - * - * @author Michel Schinz - * @version 1.0 - */ - -// TODO use a constant instead of generating empty arrays all the -// time. - -public class TypesAsValuesPhase extends Phase { - private final GenTransformer transformer; - - /** - * The list of members to add to a given class (either type - * accessors or instantiation methods). - */ - private final HashMap/*<Symbol,Symbol[]>*/ membersToAdd = - new HashMap(); - - /** The list of parameters to add to a given method. */ - private final HashMap/*<Symbol,List<Symbol>>*/ paramsToAdd = - new HashMap(); - - /** The accessor method corresponding to a given type (or class) member. */ - private final HashMap/*<Symbol, Symbol>*/ typeAccessor = - new HashMap(); - - /** The instanciation method corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ instantiator = - new HashMap(); - - /** The lazy parent class corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ lazyParentsClass = - new HashMap(); - - /** The class constructor corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ classInitialiser = - new HashMap(); - - private final HashMap/*<Symbol,Symbol>*/ tConstructor = - new HashMap(); - - private final HashMap/*<Symbol, HashSet<Symbol>>*/ constructorNeed = - new HashMap(); - - private final Definitions defs = global.definitions; - private final Primitives prims = global.primitives; - - private final Type.MethodType typeAccessorType, lazyForceType; - - private final Symbol ARRAY_CONSTRUCTOR = - defs.ARRAY_CLASS.primaryConstructor(); - - private final TEnv EENV = new TEnv(); - - private final Map/*<Symbol, Symbol>*/ predefTypes; - private final Map/*<Type, String>*/ basicTypes; - - private HashMap/*<Symbol, Ancestor[][]>*/ ancestorCache = new HashMap(); - - public TypesAsValuesPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - // If RTT are disabled, use a minimal transformer which simply - // replaces [ia]sInstanceOf with their erased counterpart. - if (global.runTimeTypes && global.target != Global.TARGET_MSIL) { - transformer = new TV_Transformer(global); - typeAccessorType = - new Type.MethodType(new Symbol[]{}, defs.TYPE_TYPE()); - lazyForceType = - new Type.MethodType(Symbol.EMPTY_ARRAY, - defs.ARRAY_TYPE(defs.SCALACLASSTYPE_TYPE())); - predefTypes = new HashMap(); - predefTypes.put(defs.DOUBLE_CLASS, defs.RTT_DOUBLE()); - predefTypes.put(defs.FLOAT_CLASS, defs.RTT_FLOAT()); - predefTypes.put(defs.LONG_CLASS, defs.RTT_LONG()); - predefTypes.put(defs.INT_CLASS, defs.RTT_INT()); - predefTypes.put(defs.SHORT_CLASS, defs.RTT_SHORT()); - predefTypes.put(defs.CHAR_CLASS, defs.RTT_CHAR()); - predefTypes.put(defs.BYTE_CLASS, defs.RTT_BYTE()); - predefTypes.put(defs.BOOLEAN_CLASS, defs.RTT_BOOLEAN()); - predefTypes.put(defs.UNIT_CLASS, defs.RTT_UNIT()); - - predefTypes.put(defs.ANY_CLASS, defs.RTT_ANY()); - predefTypes.put(defs.ANYVAL_CLASS, defs.RTT_ANYVAL()); - predefTypes.put(defs.ALLREF_CLASS, defs.RTT_ALLREF()); - predefTypes.put(defs.ALL_CLASS, defs.RTT_ALL()); - - basicTypes = new HashMap(); - basicTypes.put(defs.BOOLEAN_TYPE(), "Z"); - basicTypes.put(defs.BYTE_TYPE(), "B"); - basicTypes.put(defs.CHAR_TYPE(), "C"); - basicTypes.put(defs.DOUBLE_TYPE(), "D"); - basicTypes.put(defs.FLOAT_TYPE(), "F"); - basicTypes.put(defs.INT_TYPE(), "I"); - basicTypes.put(defs.LONG_TYPE(), "J"); - basicTypes.put(defs.SHORT_TYPE(), "S"); - - membersToAdd.put(defs.ARRAY_CLASS, new Symbol[0]); - paramsToAdd.put(ARRAY_CONSTRUCTOR, new Symbol[0]); - - ancestorCache.put(defs.OBJECT_CLASS, new Ancestor[0][]); - } else { - transformer = new TV_MiniTransformer(global); - typeAccessorType = lazyForceType = null; - predefTypes = basicTypes = null; - } - } - - /** - * Return the symbol of the accessor for the given type symbol. - */ - private Symbol getAccessorSym(Symbol typeSym) { - assert typeSym.isType(); - Symbol accessorSym = (Symbol)typeAccessor.get(typeSym); - if (accessorSym == null) { - accessorSym = typeSym.owner().newVariable(typeSym.pos, - typeSym.flags, - Names.TYPE(typeSym)); - accessorSym.setInfo(defs.TYPE_TYPE()); - typeAccessor.put(typeSym, accessorSym); - } - return accessorSym; - } - - private Symbol getInstMethSym(Symbol classSym) { - Symbol imSym = (Symbol)instantiator.get(classSym); - if (imSym == null) { - int pos = classSym.pos; - boolean isStatic = !isNestedClass(classSym); - Name imName = Names.INSTANTIATE(classSym, isStatic); - - int flags = classSym.isAbstractType() ? Modifiers.DEFERRED : 0; - - imSym = isStatic - ? classSym.newStaticMethod(pos, 0, imName) - : classSym.owner().newMethodOrFunction(pos, flags, imName); - - Symbol[] argTypes; - Symbol typesP = imSym.newVParam(pos, 0, Name.fromString("types")); - typesP.setInfo(defs.ARRAY_TYPE(defs.TYPE_TYPE())); - argTypes = new Symbol[]{ typesP }; - - imSym.setInfo(new Type.MethodType(argTypes, - isStatic - ? defs.SCALACLASSTYPE_TYPE() - : defs.TYPE_TYPE())); - - instantiator.put(classSym, imSym); - } - return imSym; - } - - private Symbol getLazyParentClassSym(Symbol classSym) { - Symbol lpcSym = (Symbol)lazyParentsClass.get(classSym); - if (lpcSym == null) { - int pos = classSym.pos; - Name lpcName = Names.LAZYPARENTS(classSym); - lpcSym = classSym.owner().newClass(pos, 0, lpcName); - - Type lpcInfo = - Type.compoundType(new Type[] { defs.LAZYPARENTS_TYPE() }, - new Scope(), - lpcSym); - lpcSym.setInfo(lpcInfo); - - Symbol lpcConstrSym = lpcSym.primaryConstructor(); - Symbol typesP = - lpcConstrSym.newVParam(pos, 0, Name.fromString("types")); - typesP.setInfo(defs.ARRAY_TYPE(defs.TYPE_TYPE())); - - lpcConstrSym.setInfo(new Type.MethodType(new Symbol[]{ typesP }, - defs.UNIT_TYPE())); - - lazyParentsClass.put(classSym, lpcSym); - } - return lpcSym; - } - - private Symbol getTConstructorSym(Symbol classSym) { - Symbol tcSym = (Symbol)tConstructor.get(classSym); - if (tcSym == null) { - int pos = classSym.pos; - boolean isStatic = !isNestedClass(classSym); - Name tcName = Names.TYPECONSTRUCTOR(classSym, isStatic); - - tcSym = isStatic - ? classSym.newStaticField(pos, 0, tcName) - : classSym.owner().newFieldOrVariable(pos, 0, tcName); - tcSym.setInfo(defs.TYPECONSTRUCTOR_TYPE()); - - tConstructor.put(classSym, tcSym); - } - return tcSym; - } - - private Symbol getClassInitSym(Symbol classSym) { - Symbol ciSym = (Symbol)classInitialiser.get(classSym); - if (ciSym == null) { - int pos = classSym.pos; - - ciSym = classSym.newStaticMethod(pos, 0, Names.CLASS_CONSTRUCTOR); - ciSym.setInfo(new Type.MethodType(Symbol.EMPTY_ARRAY, - defs.UNIT_TYPE())); - - classInitialiser.put(classSym, ciSym); - } - return ciSym; - } - - private Symbol[] membersToAdd(Symbol classSym) { - Symbol[] toAdd = (Symbol[])membersToAdd.get(classSym); - if (toAdd == null) { - HashSet seenMembers = new HashSet(); // [HACK] - ArrayList toAddL = new ArrayList(); - Scope.SymbolIterator membersIt = classSym.members().iterator(); - while (membersIt.hasNext()) { - Symbol member = membersIt.next(); - // [HACK] work around a bug in the analyzer, which - // doesn't add the module class to its owner's members - if (member.isModule()) - member = member.moduleClass(); - if (!seenMembers.add(member)) - continue; - if (member.isClass()) { - toAddL.add(getTConstructorSym(member)); - toAddL.add(getInstMethSym(member)); - } else if (member.isType()) - toAddL.add(getInstMethSym(member)); - } - - if (needsInstantiationMethod(classSym)) { - toAddL.add(getTConstructorSym(classSym)); - toAddL.add(getClassInitSym(classSym)); - toAddL.add(getInstMethSym(classSym)); - } - - toAdd = (Symbol[])toAddL.toArray(new Symbol[toAddL.size()]); - membersToAdd.put(classSym, toAdd); - } - return toAdd; - } - - private Symbol[] paramsToAdd(Symbol methSym) { - Symbol[] toAdd = (Symbol[])paramsToAdd.get(methSym); - if (toAdd == null) { - Symbol[] tparams = methSym.typeParams(); - - ArrayList toAddL = new ArrayList(); - for (int i = 0; i < tparams.length; ++i) - toAddL.add(getAccessorSym(tparams[i])); - - toAdd = (Symbol[])toAddL.toArray(new Symbol[toAddL.size()]); - paramsToAdd.put(methSym, toAdd); - } - - return toAdd; - } - - /** - * Return true iff the given symbol is not a polymorphic - * primitive, which shouldn't get type parameters as value - * parameters. - */ - private boolean monoPrimitive(Symbol sym) { - return sym.isJava() - || sym == ARRAY_CONSTRUCTOR - || sym == defs.OBJECT_SYNCHRONIZED - || sym == defs.ANY_IS - || sym == defs.ANY_IS_ERASED - || sym == defs.ANY_AS - || sym == defs.ANY_AS_ERASED; - } - - public Type transformInfo(Symbol symbol, Type type) { - if (!global.runTimeTypes) return type; - - if (symbol.isClass()) { - Symbol[] toAdd = membersToAdd(symbol); - - if (toAdd.length == 0) - return type; - else { - Scope newMembers = new Scope(symbol.members()); - - for (int i = 0; i < toAdd.length; ++i) - newMembers.enterOrOverload(toAdd[i]); - - return Type.compoundType(type.parents(), newMembers, symbol); - } - } else if (type.typeParams().length > 0 && !monoPrimitive(symbol)) { - // Polymorphic method/constructor: - // - add a value parameter for every type parameter. - switch (type) { - case PolyType(Symbol[] tparams, // : - Type.MethodType(Symbol[] vparams, Type result)): - List newVParams = - new LinkedList(Arrays.asList(paramsToAdd(symbol))); - newVParams.addAll(Arrays.asList(vparams)); - Symbol[] newVParamsA = (Symbol[]) - newVParams.toArray(new Symbol[newVParams.size()]); - - return new Type.PolyType(tparams, - new Type.MethodType(newVParamsA, - result)); - - default: - throw Debug.abort("unexpected type: ", type); - } - } else - return type; - } - - /** - * Return true iff the given type is trivial, that is if it - * has neither a prefix, nor type parameters. - */ - private boolean isTrivial(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, Type[] args): - if (sym == defs.ARRAY_CLASS) - return isTrivial(args[0]); - else - return sym.isStatic() && args.length == 0; - case SingleType(_, _): - case ThisType(_): - case CompoundType(_, _): - return false; - default: - throw Debug.abort("unexpected type", tp); - } - } - - /** - * Return true iff the given type is strongly trivial, that is - * if it and all its ancestors are trivial. - */ - private boolean isStronglyTrivial(Type tp) { - if (isTrivial(tp)) { - Type[] parents = tp.parents(); - for (int i = 0; i < parents.length; ++i) { - if (!isStronglyTrivial(parents[i])) - return false; - } - return true; - } else - return false; - } - - private boolean isNestedClass(Symbol classSym) { - return !classSym.owner().isPackageClass(); - } - - private boolean needsInstantiationMethod(Symbol classSym) { - return !(isNestedClass(classSym) || isStronglyTrivial(classSym.type())); - } - - public void apply(CompilationUnit unit) { - transformer.apply(unit); - } - - private class TV_Transformer extends TV_MiniTransformer { - private Symbol currentOwner; - private TreeList additionalTopLevelClasses; - - public TV_Transformer(Global global) { - super(global); - } - - public void apply(CompilationUnit unit) { - unit.global.log("transforming " + unit); - additionalTopLevelClasses = new TreeList(); - TreeList newUnitBody = new TreeList(transform(unit.body)); - newUnitBody.append(additionalTopLevelClasses); - additionalTopLevelClasses = null; - unit.body = newUnitBody.toArray(); - } - - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol clsSym = tree.symbol(); - - TreeList newBody = new TreeList(); - if (needsInstantiationMethod(clsSym)) { - boolean lazy = isCyclic(clsSym); - - Symbol tcSym = getTConstructorSym(clsSym); - newBody.append(tConstructorVal(clsSym, tcSym)); - Symbol ciSym = getClassInitSym(clsSym); - newBody.append(classInitialiser(clsSym, ciSym, tcSym)); - Symbol imSym = getInstMethSym(clsSym); - newBody.append(instantiatorBody(clsSym, imSym, lazy)); - - if (lazy) { - Symbol lpcSym = getLazyParentClassSym(clsSym); - Tree lpc = lazyParentsClass(clsSym, lpcSym); - additionalTopLevelClasses.append(lpc); - } - } - newBody.append(transformStatements(impl.body, impl.symbol())); - - return gen.ClassDef(clsSym, - transform(impl.parents, - clsSym.primaryConstructor()), - impl.symbol(), - newBody.toArray()); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - - if (symbol.name == Names.getScalaType && symbol.isSynthetic()) { - // Correct the body of the getScalaType method - // which, until now, was a placeholder (introduced - // by RefCheck). - return gen.DefDef(symbol, - scalaClassType(symbol.pos, - symbol.owner().type(), - symbol, - EENV)); - } else - return gen.DefDef(symbol, transform(rhs, symbol)); - - case Block(Tree[] stats, Tree value): - return gen.Block(tree.pos, - transformStatements(stats), - transform(value)); - - case ValDef(_, _, Tree tpe, Literal(AConstant.ZERO)): - // transform default values: - // val x: T = _ - // becomes - // val x: T = asValue(T).defaultValue() - Symbol symbol = getSymbolFor(tree); - Tree defaultValue = - gen.mkRef(tree.pos, - typeAsValue(tree.pos, - tpe.type, - currentOwner, - EENV), - defs.TYPE_DEFAULTVALUE()); - Tree rhs = gen.mkApply__(tree.pos, defaultValue); - return gen.ValDef(symbol, rhs); - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.ValDef(symbol, transform(rhs, symbol)); - - case New(Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs)): - if (fun.symbol() == ARRAY_CONSTRUCTOR - && targs[0].type().symbol().isParameter()) { - // Transform array creations: - // new Array[T](size) - // becomes - // asValue(T).newArray[T](size) - assert targs.length == 1; - assert vargs.length == 1; - Tree newArrayfun = gen.mkRef(tree.pos, - typeAsValue(targs[0].pos, - targs[0].type(), - currentOwner, - EENV), - defs.TYPE_NEWARRAY()); - return gen.mkApplyTV(newArrayfun, targs, vargs); - } else - return super.transform(tree); - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - Symbol funSym = fun.symbol(); - - if (funSym == defs.ANY_IS) { - assert targs.length == 1 && vargs.length == 0; - Type type = targs[0].type; - Tree expr = transform(qualifierOf(fun)); - return (isTrivial(type) && !isSpecial(type)) - ? super.transform(tree) - : genInstanceTest(tree.pos, expr, type); - } else if (funSym == defs.ANY_AS) { - // Transform instance tests: - // e.asInstanceOf[T] - // becomes: - // asValue(T).cast(e).asInstanceOf[T] - // unless T is a trivial type for which a Java - // instance test is sufficient, in which case the - // erased version of asInstanceOf is used. - assert targs.length == 1 && vargs.length == 0; - Type type = targs[0].type; - Tree expr = transform(qualifierOf(fun)); - return (isTrivial(type) && !isSpecial(type)) - ? super.transform(tree) - : genTypeCast(tree.pos, expr, type); - } else if (!monoPrimitive(funSym)) { - // Transform applications to pass types as values: - // f[T1, ...](v1, ...) - // becomes - // f[T1, ...](asValue(T1), ..., v1, ...) - Tree[] newVArgs = transform(vargs); - Tree[] finalVArgs = - new Tree[newVArgs.length + targs.length]; - for (int i = 0; i < targs.length; ++i) - finalVArgs[i] = typeAsValue(targs[i].pos, - targs[i].type, - currentOwner, - EENV); - System.arraycopy(newVArgs, 0, - finalVArgs, targs.length, - newVArgs.length); - return gen.mkApplyTV(tree.pos, - transform(fun), - targs, - finalVArgs); - } else - return super.transform(tree); - - default: - return super.transform(tree); - } - } - - private Tree[] transformStatements(Tree[] stats) { - ArrayList newStats = new ArrayList(); - int beginIdx = 0; - for (int i = 0; i < stats.length; ++i) { - Tree stat = stats[i]; - switch (stat) { - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol clsSym = stat.symbol(); - boolean lazy = isCyclic(clsSym); - Symbol tcSym = getTConstructorSym(clsSym); - newStats.add(beginIdx++, tConstructorVal(clsSym, tcSym)); - Symbol insSym = getInstMethSym(clsSym); - newStats.add(instantiatorBody(clsSym, insSym, lazy)); - if (lazy) { - Symbol lpcSym = getLazyParentClassSym(clsSym); - newStats.add(lazyParentsClass(clsSym, lpcSym)); - } - break; - - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - Symbol tpSym = stat.symbol(); - Symbol insSym = getInstMethSym(tpSym); - newStats.add(typeAccessorBody(tpSym, insSym)); - break; - } - newStats.add(transform(stat)); - } - return (Tree[])newStats.toArray(new Tree[newStats.size()]); - } - - private Tree[] transformStatements(Tree[] stats, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree[] newStats = transformStatements(stats); - this.currentOwner = bkpOwner; - return newStats; - } - - private Tree transform(Tree tree, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree newTree = transform(tree); - this.currentOwner = bkpOwner; - return newTree; - } - - private Tree[] transform(Tree[] trees, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree[] newTrees = transform(trees); - this.currentOwner = bkpOwner; - return newTrees; - } - - private int level(Symbol sym) { - Symbol superClass = sym.parents()[0].symbol(); - assert superClass != Symbol.NONE : sym; - if (superClass == defs.ANY_CLASS) - return 0; - else - return 1 + level(superClass); - } - - /** - * Return a method giving access to the given type, as a - * value. - */ - private Tree.DefDef typeAccessorBody(Symbol typSym, Symbol accSym) { - Tree rhs; - if (typSym.isAbstractType()) - rhs = Tree.Empty; - else if (typSym.isClass()) - rhs = scalaClassType(typSym.pos, typSym.type(), accSym, EENV); - else { - final Symbol[] vparams = accSym.valueParams(); - final int pos = accSym.pos; - - final HashMap varMap = new HashMap(); - Symbol[] tparams = typSym.typeParams(); - for (int i = 0; i < tparams.length; ++i) - varMap.put(tparams[i], new Integer(i)); - - TEnv tEnv = new TEnv() { - public boolean definesVar(Symbol sym) { - return varMap.containsKey(sym); - } - - public Tree treeForVar(Symbol sym) { - int idx = ((Integer)varMap.get(sym)).intValue(); - Tree array = gen.mkLocalRef(pos, vparams[0]); - return gen.mkArrayGet(pos, array, idx); - } - }; - - rhs = typeAsValue(typSym.pos, typSym.type(), accSym, tEnv); - } - return gen.DefDef(accSym, rhs); - } - - private Tree tConstructorVal(Symbol clsSym, Symbol tcSym) { - return gen.ValDef(tcSym, - tcSym.isStatic() - ? Tree.Empty - : tConstructorRHS(tcSym.pos, clsSym, tcSym)); - } - - private Tree classInitialiser(Symbol clsSym, - Symbol ciSym, - Symbol tcSym) { - if (tcSym.isStatic()) { - int pos = tcSym.pos; - Tree rhs = tConstructorRHS(pos, clsSym, ciSym); - Tree assign = gen.Assign(pos, gen.Ident(pos, tcSym), rhs); - - return gen.DefDef(ciSym, assign); - } else - return Tree.Empty; - } - - private Tree tConstructorRHS(int pos, Symbol clsSym, Symbol owner) { - int zCount = 0, mCount = 0, pCount = 0; - Symbol[] tparams = clsSym.typeParams(); - - for (int i = 0; i < tparams.length; ++i) { - if ((tparams[i].flags & Modifiers.COVARIANT) != 0) - ++pCount; - else if ((tparams[i].flags & Modifiers.CONTRAVARIANT) != 0) - ++mCount; - else - ++zCount; - } - - Ancestor[][] ancestors = computeAncestors(clsSym); - int[] ancestorCode = getAncestorCode(ancestors); - - Tree outer = isNestedClass(clsSym) - ? (clsSym.owner().isClass() - ? gen.This(pos, clsSym.owner()) - : gen.mkGlobalRef(pos, defs.TYPECONSTRUCTOR_FUNCTIONOUTER())) - : gen.mkNullLit(pos); - - Tree[] tcArgs = new Tree[] { - gen.mkIntLit(pos, level(clsSym)), - gen.mkSymbolNameLit(pos, clsSym), - outer, - gen.mkIntLit(pos, zCount), - gen.mkIntLit(pos, mCount), - gen.mkIntLit(pos, pCount), - gen.mkIntLit(pos, ancestors.length), - ancestorCode.length == 0 - ? gen.mkNullLit(pos) - : mkNewIntLitArray(pos, getAncestorCode(ancestors), owner) - }; - - Symbol tcConst = defs.TYPECONSTRUCTOR_CLASS.primaryConstructor(); - Tree tcCall = - gen.mkApply_V(pos, gen.mkGlobalRef(pos, tcConst), tcArgs); - return gen.New(pos, tcCall); - } - - private Tree mkNewIntLitArray(int pos, int[] values, Symbol owner) { - Tree[] intLits = new Tree[values.length]; - for (int i = 0; i < values.length; ++i) - intLits[i] = gen.mkIntLit(pos, values[i]); - return gen.mkNewArray(pos, defs.INT_TYPE(), intLits, owner); - } - - private Tree lazyParentsClass(Symbol clsSym, Symbol lazyClsSym) { - int pos = clsSym.pos; - - Symbol typesSym = lazyClsSym.primaryConstructor().valueParams()[0]; - - Symbol forceSym = lazyClsSym.newMethod(pos, 0, Names.force); - forceSym.setInfo(lazyForceType); - lazyClsSym.members().enter(forceSym); - Tree.DefDef forceDef = - gen.DefDef(forceSym, - parentsArray(pos, clsSym, typesSym, forceSym)); - - return gen.ClassDef(lazyClsSym, new Tree[] { forceDef }); - } - - /** - * Return a method to instantiate the given type. - */ - private Tree.DefDef instantiatorBody(Symbol clsSym, - Symbol insSym, - boolean lazy) { - // TODO fix flags for all symbols below - final int pos = clsSym.pos; - final Symbol typesArr = insSym.valueParams()[0]; - - Tree[] body = new Tree[2]; - - // Generate call to "getInstantiation" method of - // constructor. - Tree getInstFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_GETINSTANTIATION()); - - Tree[] getInstArgs = new Tree[]{ gen.mkLocalRef(pos, typesArr) }; - - Symbol instVal = - insSym.newVariable(pos, 0, Name.fromString("inst")); - instVal.setInfo(defs.SCALACLASSTYPE_TYPE()); - - Tree instValDef = - gen.ValDef(instVal, - gen.mkApply_V(pos, getInstFun, getInstArgs)); - - // Generate test to see if a call to "instantiate" is - // necessary. - Tree cond = - gen.mkApply_V(pos, - gen.Select(pos, - gen.mkLocalRef(pos, instVal), - defs.ANY_BANGEQ), - new Tree[] { gen.mkNullLit(pos) }); - Tree thenP = gen.mkLocalRef(pos, instVal); - Tree elseP = lazy - ? lazyInstantiateCall(pos, clsSym, typesArr) - : strictInstantiateCall(pos, clsSym, typesArr, insSym); - Tree ifExpr = - gen.If(pos, cond, thenP, elseP, defs.SCALACLASSTYPE_TYPE()); - - return gen.DefDef(insSym, gen.mkBlock(pos, instValDef, ifExpr)); - } - - private Tree strictInstantiateCall(int pos, - Symbol clsSym, - Symbol tpArraySym, - Symbol owner) { - Tree instFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_INSTANTIATE()); - Tree[] instArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym), - parentsArray(pos, clsSym, tpArraySym, owner) - }; - return gen.mkApply_V(pos, instFun, instArgs); - } - - private Tree lazyInstantiateCall(int pos, - Symbol clsSym, - Symbol tpArraySym) { - Tree instFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_INSTANTIATE()); - Symbol lpcSym = getLazyParentClassSym(clsSym); - Tree lazyConstr = - gen.mkPrimaryConstructorLocalRef(pos, lpcSym); - Tree[] lazyConstrArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym) - }; - Tree[] instArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym), - gen.New(pos, gen.mkApply_V(lazyConstr, lazyConstrArgs)) - }; - return gen.mkApply_V(pos, instFun, instArgs); - } - - private Tree parentsArray(final int pos, - final Symbol clsSym, - final Symbol tpArraySym, - final Symbol owner) { - final HashMap varMap = new HashMap(); - final Symbol[] tparams = clsSym.typeParams(); - for (int i = 0; i < tparams.length; ++i) - varMap.put(tparams[i], new Integer(i)); - - // Type environment mapping the type parameters of the - // class to their corresponding element in the "types" - // array passed to this instantiator. - TEnv tEnv = new TEnv() { - public boolean definesVar(Symbol sym) { - return varMap.containsKey(sym); - } - public Tree treeForVar(Symbol sym) { - int idx = ((Integer)varMap.get(sym)).intValue(); - Tree array = gen.mkLocalRef(pos, tpArraySym); - return gen.mkArrayGet(pos, array, idx); - } - public boolean definesVarArray(Symbol[] syms) { - if (syms.length == tparams.length) { - for (int i = 0; i < syms.length; ++i) { - if (syms[i] != tparams[i]) - return false; - } - return true; - } else - return false; - } - public Tree treeForVarArray(Symbol[] syms) { - assert definesVarArray(syms); - return gen.mkLocalRef(pos, tpArraySym); - } - }; - - Type[] parents = clsSym.parents(); - TreeList parentTypes = new TreeList(); - for (int i = 0; i < parents.length; ++i) { - Type parent = parents[i]; - if (!isStronglyTrivial(parent)) - parentTypes.append(typeAsValue(pos, parent, owner, tEnv)); - } - boolean emptyParents = (parentTypes.length() == 0); - return emptyParents - ? gen.mkGlobalRef(pos, defs.SCALACLASSTYPE_EMPTYARRAY()) - : gen.mkNewArray(pos, - defs.SCALACLASSTYPE_TYPE(), - parentTypes.toArray(), - owner); - } - - /** - * Generate code to test if the given expression is an - * instance of the given type. - */ - private Tree genInstanceTest(int pos, Tree expr, Type tp) { - Tree tpVal = typeAsValue(pos, tp, currentOwner, EENV); - - if (isKnowClassType(tp)) { - Symbol val = - currentOwner.newVariable(pos, - Modifiers.SYNTHETIC, - Names.LOCAL(currentOwner)); - val.setType(expr.type); - - Tree valDef = gen.ValDef(val, expr); - - Tree cheapTest = - gen.mkIsInstanceOf(pos, gen.mkLocalRef(pos, val), tp, true); - Symbol isNonTrivialInst = defs.CLASSTYPE_ISNONTRIVIALINSTANCE(); - Tree scalaTpVal = gen.mkAsInstanceOf(pos, - tpVal, - defs.CLASSTYPE_TYPE(), - true); - Tree expensiveTest = - gen.mkApply_V(pos, - gen.Select(pos, scalaTpVal, isNonTrivialInst), - new Tree[] { gen.mkLocalRef(pos, val) }); - - Tree bothTests = - gen.mkApply_V(pos, - gen.Select(pos, - cheapTest, - defs.BOOLEAN_AND()), - new Tree[] { expensiveTest }); - - return gen.mkBlock(pos, valDef, bothTests); - } else { - Tree fun = gen.Select(pos, tpVal, defs.TYPE_ISINSTANCE()); - return gen.mkApply_V(pos, fun, new Tree[] { expr }); - } - } - - /** - * Generate code to cast the given value to the given type. - */ - private Tree genTypeCast(int pos, Tree expr, Type tp) { - Tree tpVal = typeAsValue(pos, tp, currentOwner, EENV); - Tree fun = gen.Select(pos, tpVal, defs.TYPE_CAST()); - Tree castCall = gen.mkApply_V(pos, fun, new Tree[] { expr }); - return gen.mkAsInstanceOf(pos, castCall, tp); - } - - private boolean isSpecial(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, _): - return (sym == defs.ANY_CLASS) - || (sym == defs.ANYVAL_CLASS) - || (sym == defs.ALLREF_CLASS) - || (sym == defs.ALL_CLASS); - default: - return false; - } - } - - private boolean isKnowClassType(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, _): - return (sym != defs.ARRAY_CLASS) && !sym.isParameter(); - default: - return false; - } - } - - private void addConstructorsNeededBy(HashSet roots, - Type tp, - HashSet set){ - switch (tp) { - case TypeRef(_, Symbol pSym, Type[] args): - if (!pSym.isParameter()) { - set.add(pSym); - set.addAll(constructorsNeededBy(roots, pSym)); - for (int i = 0; i < args.length; ++i) - addConstructorsNeededBy(roots, args[i], set); - } - break; - case CompoundType(Type[] parts, _): - for (int i = 0; i < parts.length; ++i) - addConstructorsNeededBy(roots, parts[i], set); - default: - ; // nothing to do - } - } - - private HashSet constructorsNeededBy(HashSet roots, Symbol sym) { - HashSet constr = new HashSet(); - if (roots.add(sym)) { - Type[] parents = sym.parents(); - for (int i = 0; i < parents.length; ++i) - addConstructorsNeededBy(roots, parents[i], constr); - } - return constr; - } - - private HashSet constructorsNeededBy(Symbol sym) { - HashSet constr = (HashSet)constructorNeed.get(sym); - if (constr == null) { - constr = constructorsNeededBy(new HashSet(), sym); - constructorNeed.put(sym, constr); - } - return constr; - } - - private boolean isCyclic(Symbol sym) { - HashSet constrs = constructorsNeededBy(sym); - if (constrs.contains(sym)) - return true; - Iterator constrsIt = constrs.iterator(); - while (constrsIt.hasNext()) { - Symbol constr = (Symbol)constrsIt.next(); - if (constr.isAbstractType()) - return true; - } - return false; - } - - /** - * Transform a type into a tree representing it. - */ - private Tree typeAsValue(int pos, Type tp, Symbol owner, TEnv env) { - switch (tp) { - case ConstantType(Type base, _): - return typeAsValue(pos, base, owner, env); - - case TypeRef(Type pre, Symbol sym, Type[] args): - if (env.definesVar(sym)) { - assert args.length == 0; - return env.treeForVar(sym); - } else if (sym == defs.ARRAY_CLASS) { - assert args.length == 1; - return arrayType(pos, args[0], owner, env); - } else if (predefTypes.containsKey(sym)) { - return gen.mkGlobalRef(pos, (Symbol)predefTypes.get(sym)); - } else if (sym.isJava()) { - assert args.length <= 1 - : Debug.show(sym) + " " + args.length; - return javaClassType(pos, sym); - } else if (!sym.isParameter()) { - // Reference to a "global" type. - return scalaClassType(pos, tp, owner, env); - } else { - assert !isValuePrefix(pre) : tp; - return gen.mkLocalRef(pos, getAccessorSym(sym)); - } - - case SingleType(Type pre, Symbol sym): - return singleType(pos, (Type.SingleType)tp); - - case ThisType(Symbol sym): - return thisType(pos, sym); - - case CompoundType(Type[] parts, Scope members): - return compoundType(pos, parts, members, owner, env); - - default: - throw Debug.abortIllegalCase(tp); - } - } - - private Tree arrayType(int pos, - Type elemType, - Symbol owner, - TEnv env) { - Type realElemType = elemType; - int dimensions = 1; - while (realElemType.symbol() == defs.ARRAY_CLASS) { - realElemType = realElemType.typeArgs()[0]; - ++dimensions; - } - - if (isTrivial(elemType)) { - Tree nameLit; - if (basicTypes.containsKey(elemType)) - nameLit = - gen.mkStringLit(pos, (String)basicTypes.get(elemType)); - else - nameLit = gen.mkSymbolNameLit(pos, realElemType.symbol()); - - Tree constr = - gen.mkGlobalRef(pos, defs.JAVACLASSTYPE_JAVAARRAYTYPE()); - Tree[] args = new Tree[]{ - nameLit, - gen.mkIntLit(pos, dimensions) - }; - return gen.mkApply_V(constr, args); - } else { - Tree constr = - gen.mkGlobalRef(pos, - defs.JAVAREFARRAYTYPE_JAVAREFARRAYTYPE()); - Tree[] args = new Tree[]{ - typeAsValue(pos, elemType, owner, env), - gen.mkIntLit(pos, dimensions) - }; - return gen.mkApply_V(constr, args); - } - } - - private Tree javaClassType(int pos, Symbol sym) { - Tree constr = - gen.mkGlobalRef(pos, defs.JAVACLASSTYPE_JAVACLASSTYPE()); - Tree nameLit = gen.mkSymbolNameLit(pos, sym); - Tree[] args = new Tree[] { nameLit }; - return gen.mkApply_V(constr, args); - } - - private Tree thisType(int pos, Symbol sym) { - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, defs.SINGLETYPE_CLASS); - Tree[] args = new Tree[] { gen.This(pos, sym) }; - return gen.New(pos, gen.mkApply_V(constr, args)); - } - - private Tree singleType(int pos, Type.SingleType tp) { - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, defs.SINGLETYPE_CLASS); - Tree[] args = new Tree[] { gen.mkQualifier(pos, tp) }; - return gen.New(pos, gen.mkApply_V(constr, args)); - } - - private Tree compoundType(int pos, - Type[] parts, - Scope members, - Symbol owner, - TEnv env) { - Tree[] partsT = new Tree[parts.length]; - for (int i = 0; i < parts.length; ++i) - partsT[i] = typeAsValue(pos, parts[i], owner, env); - - Tree[] constrArgs = new Tree[] { - gen.mkNewArray(pos, defs.CLASSTYPE_TYPE(), partsT, owner), - gen.mkBooleanLit(pos, members.isEmpty()) - }; - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, - defs.COMPOUNDTYPE_CLASS); - return gen.New(pos, gen.mkApply_V(constr, constrArgs)); - } - - private Tree scalaClassType(int pos, Type tp, Symbol owner, TEnv env) { - if (isStronglyTrivial(tp)) - return javaClassType(pos, tp.symbol()); - - switch (tp) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Symbol insSym = getInstMethSym(sym); - Tree preFun = (isNestedClass(sym) && sym.owner().isClass()) - ? gen.Select(pos, gen.mkQualifier(pos, pre), insSym) - : gen.Ident(pos, insSym); - - Tree insArg; - int[] perm = typeParamsPermutation(sym.typeParams()); - Symbol[] permArgs = new Symbol[args.length]; - for (int i = 0; i < args.length; ++i) - permArgs[i] = args[perm[i]].symbol(); - - if (env.definesVarArray(permArgs)) - insArg = env.treeForVarArray(permArgs); - else { - Tree[] tps = new Tree[args.length]; - for (int i = 0; i < args.length; ++i) - tps[i] = typeAsValue(pos, args[perm[i]], owner, env); - insArg = gen.mkNewArray(pos, defs.TYPE_TYPE(), tps, owner); - } - - return gen.mkApply_V(pos, preFun, new Tree[] { insArg }); - - default: - throw Debug.abort("unexpected type: ", tp); - } - } - - private final int VARIANT = - Modifiers.COVARIANT | Modifiers.CONTRAVARIANT; - - /** - * Compute the (unique) permutation which puts all invariant - * type parameters first, followed by the contravariant ones, - * then the covariants, preserving the relative ordering of - * arguments with same variance. - */ - private int[] typeParamsPermutation(Symbol[] params) { - int[] tparamsPerm = new int[params.length]; - int permIdx = 0; - - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & VARIANT) == 0) - tparamsPerm[permIdx++] = i; - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & Modifiers.CONTRAVARIANT) != 0) - tparamsPerm[permIdx++] = i; - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & Modifiers.COVARIANT) != 0) - tparamsPerm[permIdx++] = i; - assert permIdx == tparamsPerm.length; - - return tparamsPerm; - } - - private boolean isValuePrefix(Type pre) { - switch (pre) { - case ThisType(Symbol clazz): - return !(clazz.isPackage() || clazz.isNone()); - case NoPrefix: - return false; - default: - return true; - } - } - - private Ancestor[][] computeAncestors0(Symbol classSym) { - Symbol[] nstParents = notStronglyTrivialParents(classSym); - int level = level(classSym); - ArrayList/*<Ancestor>*/[] ancestor = new ArrayList[level + 1]; - - for (int l = 0; l < ancestor.length; ++l) - ancestor[l] = new ArrayList(); - - if (!isTrivial(classSym.type())) - ancestor[level].add(new Ancestor(classSym, -1, -1)); - - // Go over parents from left to right and add missing - // ancestors to the set, remembering where they come from. - for (int p = 0; p < nstParents.length; ++p) { - Symbol parentSymbol = nstParents[p]; - Ancestor[][] parentAncestors = computeAncestors(parentSymbol); - assert parentAncestors.length <= ancestor.length; - - for (int l = 0; l < parentAncestors.length; ++l) { - ArrayList/*<Ancestor>*/ myRow = ancestor[l]; - Ancestor[] parentRow = parentAncestors[l]; - parentRowLoop: - for (int i = 0; i < parentRow.length; ++i) { - Symbol sym = parentRow[i].symbol; - assert !isTrivial(sym.type()) : sym; - - Iterator myRowIt = myRow.iterator(); - while (myRowIt.hasNext()) { - Ancestor myAncestor = (Ancestor)myRowIt.next(); - if (myAncestor.symbol == sym) - continue parentRowLoop; - } - myRow.add(new Ancestor(sym, p, i)); - } - } - } - - int ancestorsLen = ancestor.length; - while (ancestorsLen > 0 && ancestor[ancestorsLen - 1].isEmpty()) - --ancestorsLen; - - Ancestor[][] finalAncestor = new Ancestor[ancestorsLen][]; - for (int i = 0; i < finalAncestor.length; ++i) { - finalAncestor[i] = (Ancestor[]) - ancestor[i].toArray(new Ancestor[ancestor[i].size()]); - } - - return finalAncestor; - } - - /** Return the non-trivial ancestors of the class */ - private Ancestor[][] computeAncestors(Symbol classSym) { - Ancestor[][] ancestor = (Ancestor[][])ancestorCache.get(classSym); - if (ancestor == null) { - ancestor = computeAncestors0(classSym); - ancestorCache.put(classSym, ancestor); -// debugPrintAncestor(classSym, ancestor); - } - return ancestor; - } - - /** Return the parents which are not strongly trivial. */ - private Symbol[] notStronglyTrivialParents(Symbol classSym) { - Type[] parentTypes = classSym.parents(); - ArrayList nstParents = new ArrayList(parentTypes.length); - for (int i = 0; i < parentTypes.length; ++i) { - if (!isStronglyTrivial(parentTypes[i])) - nstParents.add(parentTypes[i].symbol()); - } - return (Symbol[]) - nstParents.toArray(new Symbol[nstParents.size()]); - } - - private int[] getAncestorCode(Ancestor[][] ancestor) { - ArrayList/*<Ancestor>*/[] prunedRows = - new ArrayList[ancestor.length]; - - int totalSize = 0; - for (int l = 0; l < ancestor.length; ++l) { - Ancestor[] row = ancestor[l]; - ArrayList/*<Ancestor>*/ prunedRow = new ArrayList(row.length); - for (int i = 0; i < row.length; ++i) { - if (row[i].parentIndex > 0) - prunedRow.add(row[i]); - } - prunedRows[l] = prunedRow; - if (!prunedRow.isEmpty()) - totalSize += 2 + 2 * prunedRow.size(); - } - - int[] res = new int[totalSize]; - int i = 0; - for (int l = 0; l < prunedRows.length; ++l) { - ArrayList row = prunedRows[l]; - if (!row.isEmpty()) { - res[i++] = l; - res[i++] = row.size(); - Iterator ancIt = row.iterator(); - while (ancIt.hasNext()) { - Ancestor anc = (Ancestor)ancIt.next(); - res[i++] = anc.parentIndex; - res[i++] = anc.position; - } - } - } - assert i == totalSize; - return res; - } - } - - /** - * Minimalistic transformer, which simply transforms calls to - * isInstanceOf/asInstanceOf by calls to their erased - * counterparts. Used when full run time types are disabled. - */ - private class TV_MiniTransformer extends GenTransformer { - private final Definitions defs; - - public TV_MiniTransformer(Global global) { - super(global); - defs = global.definitions; - } - - public Tree transform(Tree tree) { - switch (tree) { - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - Symbol funSym = fun.symbol(); - if (funSym == defs.ANY_IS || funSym == defs.ANY_AS) { - assert vargs.length == 0; - Symbol erasedSym = (funSym == defs.ANY_AS) - ? defs.ANY_AS_ERASED - : defs.ANY_IS_ERASED; - return gen.mkApplyTV(tree.pos, - gen.Select(fun.pos, - transform(qualifierOf(fun)), - erasedSym), - targs, - vargs); - } else - return super.transform(tree); - - default: - return super.transform(tree); - } - } - } - - /** - * Extract qualifier from a tree, which must be a Select node. - */ - private Tree qualifierOf(Tree tree) { - switch (tree) { - case Select(Tree qualifier, _): return qualifier; - default: throw Debug.abort("cannot extract qualifier from ", tree); - } - } - - // Debugging function - private void debugPrintAncestor(Symbol sym, Ancestor[][] ancestor) { - System.out.println("ancestor for " + Debug.show(sym)); - for (int l = 0; l < ancestor.length; ++l) { - System.out.print(" [" + l + "] "); - for (int i = 0; i < ancestor[l].length; ++i) { - if (i > 0) - System.out.print(" "); - System.out.println(" " + Debug.show(ancestor[l][i].symbol) - + "/par" + ancestor[l][i].parentIndex - + "/pos" + ancestor[l][i].position); - } - if (ancestor[l].length == 0) - System.out.println("<empty>"); - } - } - - ////////////////////////////////////////////////////////////////////// - - private static class TEnv { - public boolean definesVar(Symbol sym) { - return false; - } - public Tree treeForVar(Symbol sym) { - throw Debug.abort("no tree for variable " + sym); - } - public boolean definesVarArray(Symbol[] syms) { - return false; - } - public Tree treeForVarArray(Symbol[] syms) { - throw Debug.abort("no tree for variable array " + syms); - } - } - - private static class Ancestor { - public static final Ancestor[] EMPTY_ARRAY = new Ancestor[0]; - - public final Symbol symbol; - public final int parentIndex; - public final int position; - - public Ancestor(Symbol symbol, int parentIndex, int position) { - this.symbol = symbol; - this.parentIndex = parentIndex; - this.position = position; - } - } -} diff --git a/sources/scalac/transformer/WholeProgPhase.java b/sources/scalac/transformer/WholeProgPhase.java deleted file mode 100644 index 7591352c21..0000000000 --- a/sources/scalac/transformer/WholeProgPhase.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; - -/** - * This class represents the wholeprog phase for the java version of - * the compiler. It doesn't do anything but permit to make a bridge - * between the java implementation of Socos and the scala one. See - * scala.tools.scalac.wholeprog.WholeProgPhase for implementation. - */ -public abstract class WholeProgPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public WholeProgPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## -} diff --git a/sources/scalac/typechecker/AnalyzerPhase.java b/sources/scalac/typechecker/AnalyzerPhase.java deleted file mode 100644 index 517d4713dc..0000000000 --- a/sources/scalac/typechecker/AnalyzerPhase.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.typechecker; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.ast.TreeGen; -import scalac.symtab.Definitions; -import scalac.symtab.Symbol; - - -public abstract class AnalyzerPhase extends Phase { - - public final TreeGen gen; - - /** Initializes this instance. */ - public AnalyzerPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - global.definitions = new Definitions(global); - this.gen = new TreeGen(global, global.make); - } - - public abstract void addConsoleImport(Symbol module); - -} diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java deleted file mode 100644 index 528ca7b47d..0000000000 --- a/sources/scalac/typechecker/Infer.java +++ /dev/null @@ -1,23 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.typechecker; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -public abstract class Infer { - - /** throw a type error if arguments not within bounds. - */ - public abstract void checkBounds(Symbol[] tparams, Type[] targs, String prefix); - - - public abstract Type skipViewParams(Symbol[] tparams, Type tp); - -} diff --git a/sources/scalac/util/AbstractFileReader.java b/sources/scalac/util/AbstractFileReader.java deleted file mode 100644 index bf3d6f437d..0000000000 --- a/sources/scalac/util/AbstractFileReader.java +++ /dev/null @@ -1,113 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.util; - -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -public class AbstractFileReader { - - /** the buffer containing the file - */ - public byte[] buf; - - /** the current input pointer - */ - public int bp; - - /** the file path name - */ - public final String path; - - /** constructor - */ - public AbstractFileReader(AbstractFile f) throws IOException { - buf = f.read(); - bp = 0; - path = f.getPath(); - } - - /** return byte at offset 'pos' - */ - public byte byteAt(int pos) { - return buf[pos]; - } - - /** read a byte - */ - public byte nextByte() { - return buf[bp++]; - } - - /** read some bytes - */ - public byte[] nextBytes(int len) { - byte[] res = new byte[len]; - System.arraycopy(buf, bp, res, 0, len); - bp += len; - return res; - } - - /** read a character - */ - public char nextChar() { - return - (char)(((buf[bp++] & 0xff) << 8) + - (buf[bp++] & 0xff)); - } - - /** read an integer - */ - public int nextInt() { - return ((buf[bp++] & 0xff) << 24) + - ((buf[bp++] & 0xff) << 16) + - ((buf[bp++] & 0xff) << 8) + - (buf[bp++] & 0xff); - } - - /** extract a character at position bp from buf - */ - public char getChar(int mybp) { - return (char)(((buf[mybp] & 0xff) << 8) + (buf[mybp+1] & 0xff)); - } - - /** extract an integer at position bp from buf - */ - public int getInt(int mybp) { - return ((buf[mybp ] & 0xff) << 24) + - ((buf[mybp+1] & 0xff) << 16) + - ((buf[mybp+2] & 0xff) << 8) + - (buf[mybp+3] & 0xff); - } - - /** extract a long integer at position bp from buf - */ - public long getLong(int mybp) { - return ((long)(getInt(mybp)) << 32) + (getInt(mybp + 4) & 0xffffffffL); - } - - /** extract a float at position bp from buf - */ - public strictfp float getFloat(int mybp) { - return Float.intBitsToFloat(getInt(mybp)); - } - - /** extract a double at position bp from buf - */ - public strictfp double getDouble(int mybp) { - return Double.longBitsToDouble(getLong(mybp)); - } - - /** skip next 'n' bytes - */ - public void skip(int n) { - bp += n; - } -} diff --git a/sources/scalac/util/ArrayApply.java b/sources/scalac/util/ArrayApply.java deleted file mode 100644 index 087278af5b..0000000000 --- a/sources/scalac/util/ArrayApply.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -public abstract class ArrayApply { - - //######################################################################## - // Arrays interface - Object - - public static String toString(Object[] src) { - return append(new StringBuffer(), src).toString(); - } - - public static String toString(Object[] src, String infix) { - return append(new StringBuffer(), src, infix).toString(); - } - - public static String toString(Object[] src, String prefix, String infix, - String suffix) - { - return append(new StringBuffer(), src, prefix,infix,suffix).toString(); - } - - //######################################################################## - // Arrays interface - StringBuffer - - public static StringBuffer append(StringBuffer buffer, Object[] src) { - return append(buffer, src, "[", ",", "]"); - } - - public static StringBuffer append(StringBuffer buffer, Object[] src, - String infix) - { - return append(buffer, src, "", infix, ""); - } - - public static StringBuffer append(StringBuffer buffer, Object[] src, - String prefix, String infix, String suffix) - { - buffer.append(prefix); - for (int i = 0; i < src.length; i++) { - if (i > 0) buffer.append(infix); - buffer.append(src[i]); - } - buffer.append(suffix); - return buffer; - } -} diff --git a/sources/scalac/util/Debug.java b/sources/scalac/util/Debug.java deleted file mode 100644 index 3e889beb62..0000000000 --- a/sources/scalac/util/Debug.java +++ /dev/null @@ -1,503 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import scala.tools.util.debug.Debugger; -import scala.tools.util.debug.ToStringDebugger; - -import scalac.Global; -import scalac.ast.Tree; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** - * Debugging class, used e.g. to obtain string representations of - * compiler data structures that are not "pretty-printed" and thus - * easier to relate to the source code. - * - * All methods are static to be easily useable in any context. - * - * @author Michel Schinz - * @version 1.0 - */ -public class Debug extends scala.tools.util.debug.Debug { - - //######################################################################## - // Private Initialization - - /** - * Forces the initialization of this class. Returns the boolean - * value true so that it can be invoked from an assert statement. - */ - public static boolean initialize() { - // nothing to do, everything is done in the static initializer - return true; - } - - static { - addDebugger(new ToStringDebugger(Tree.class)); - addDebugger(new ToStringDebugger(Type.class)); - addDebugger(SymbolDebugger.object); - addDebugger(ScopeDebugger.object); - } - - //######################################################################## - // Public Methods - Logging - - public static boolean log(Object a) { - return logAll(new Object[] {a}); - } - - public static boolean log(Object a, Object b) { - return logAll(new Object[] {a, b}); - } - - public static boolean log(Object a, Object b, Object c) { - return logAll(new Object[] {a, b, c}); - } - - public static boolean log(Object a, Object b, Object c, Object d) { - return logAll(new Object[] {a, b, c, d}); - } - - public static boolean logAll(Object[] args) { - return Global.instance.log(showAll(args, null)); - } - - //######################################################################## - // showTree - - private static void append(StringBuffer buf, Name[] names) { - for (int i = 0; i < names.length; i++) { - if (i > 0) buf.append(","); - append(buf, names[i]); - } - } - - private static void append(StringBuffer buf, Name name) { - buf.append("\"" + name + '"'); - } - - private static void append(StringBuffer buf, String str) { - buf.append("\"" + str + '"'); - } - - private static void append(StringBuffer buf, Tree[] trees, boolean showType) { - buf.append('['); - for (int i = 0; i < trees.length; i++) { - if (i > 0) buf.append(','); - append(buf, trees[i], showType); - } - buf.append(']'); - } - - private static void append(StringBuffer buf, Tree[][] trees) { - for (int i = 0; i < trees.length; i++) { - buf.append('['); - append(buf, trees[i]); - buf.append(']'); - } - } - - private static void append(StringBuffer buf, Tree tree, boolean showType) { - switch (tree) { - case Empty: - buf.append("Empty("); - break; - case Attributed(Tree attribute, Tree definition): - buf.append("Attributed("); - append(buf, attribute); - buf.append(','); - append(buf, definition); - break; - case DocDef(String comment, Tree definition): - buf.append("DocDef("); - append(buf, comment); - buf.append(','); - append(buf, definition); - break; - case ClassDef(int mods, Name name, Tree.AbsTypeDef[] tparams, - Tree.ValDef[][] vparams, Tree tpe, Tree.Template impl): - buf.append("ClassDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tparams); - buf.append(','); - append(buf, vparams); - buf.append(','); - append(buf, tpe); - buf.append(','); - append(buf, impl); - break; - case PackageDef(Tree packaged, Tree.Template impl): - buf.append("PackageDef("); - append(buf, packaged); - buf.append(','); - append(buf, impl); - break; - case ModuleDef(int mods, Name name, Tree tpe, Tree.Template impl): - buf.append("ModuleDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tpe); - buf.append(','); - append(buf, impl); - break; - case ValDef(int mods, Name name, Tree tpe, Tree rhs): - buf.append("ValDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tpe, showType); - buf.append(','); - append(buf, rhs, showType); - break; - case PatDef(int mods, Tree pat, Tree rhs): - buf.append("PatDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, pat); - buf.append(','); - append(buf, rhs); - break; - case DefDef(int mods, Name name, Tree.AbsTypeDef[] tparams, - Tree.ValDef[][] vparams, Tree tpe, Tree rhs): - buf.append("DefDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tparams); - buf.append(','); - append(buf, vparams); - buf.append(','); - append(buf, tpe); - buf.append(','); - append(buf, rhs); - break; - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - buf.append("AbsTypeDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, rhs); - buf.append(','); - append(buf, lobound); - break; - case AliasTypeDef(int mods, Name name, Tree.AbsTypeDef[] tparams, Tree rhs): - buf.append("AliasTypeDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tparams); - buf.append(','); - append(buf, rhs); - break; - case Import(Tree expr, Name[] selectors): - buf.append("Import("); - append(buf, expr); - buf.append(","); - append(buf, selectors); - break; - case CaseDef(Tree pat, Tree guard, Tree body): - buf.append("CaseDef("); - buf.append(","); - append(buf, pat); - buf.append(","); - append(buf, guard); - buf.append(","); - append(buf, body); - break; - case Template(Tree[] parents, Tree[] body): - buf.append("Template("); - append(buf, parents); - buf.append(','); - append(buf, body); - break; - case LabelDef(Name name, Tree.Ident[] params, Tree rhs): - buf.append("LabelDef("); - buf.append(","); - append(buf, name); - buf.append(','); - append(buf, params); - buf.append(','); - append(buf, rhs); - break; - case Block(Tree[] stats, Tree expr): - buf.append("Block("); - append(buf, stats); - buf.append(','); - append(buf, expr); - break; - case Sequence(Tree[] trees): - buf.append("Sequence("); - buf.append(','); - append(buf, trees); - break; - case Alternative(Tree[] trees): - buf.append("Alternative("); - buf.append(','); - append(buf, trees); - break; - case Bind(Name name, Tree rhs): - buf.append("Bind("); - append(buf, name); - buf.append(','); - append(buf, rhs); - break; - case Visitor(Tree.CaseDef[] cases): - buf.append("ClassDef("); - append(buf, cases); - break; - case Function(Tree.ValDef[] vparams, Tree body): - buf.append("Function("); - append(buf, vparams); - buf.append(','); - append(buf, body); - break; - case Assign(Tree lhs, Tree rhs): - buf.append("Assign("); - append(buf, lhs); - buf.append(','); - append(buf, rhs); - break; - case If(Tree cond, Tree thenp, Tree elsep): - buf.append("If("); - append(buf, cond); - buf.append(','); - append(buf, thenp); - buf.append(','); - append(buf, elsep); - break; - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - buf.append("Switch("); - buf.append(','); - append(buf, test); - buf.append(','); - buf.append(tags); // TODO - buf.append(','); - append(buf, bodies); - buf.append(","); - append(buf, otherwise); - break; - case Return(Tree expr): - buf.append("Return("); - append(buf, expr, showType); - buf.append(')'); - break; - case Throw(Tree expr): - buf.append("Throw("); - append(buf, expr, showType); - break; - case New(Tree init): - buf.append("New("); - append(buf, init, showType); - break; - case Create(Tree qualifier, Tree[] targs): - buf.append("Create("); - append(buf, qualifier); - buf.append(','); - append(buf, targs); - break; - case Typed(Tree expr, Tree tpe): - buf.append("Typed("); - append(buf, expr, showType); - buf.append(","); - append(buf, tpe, showType); - break; - case TypeApply(Tree fun, Tree[] args): - buf.append("TypeApply("); - append(buf, fun, showType); - buf.append(','); - append(buf, args, showType); - break; - case Apply(Tree fun, Tree[] args): - buf.append("Apply("); - append(buf, fun, showType); - buf.append(','); - append(buf, args, showType); - break; - case Super(Name qualifier, Name mixin): - buf.append("Super("); - append(buf, qualifier); - buf.append(','); - append(buf, mixin); - break; - case This(Name qualifier): - buf.append("This("); - append(buf, qualifier); - break; - case Select(Tree qualifier, Name selector): - buf.append("Select("); - append(buf, qualifier, showType); - buf.append(','); - append(buf, selector); - break; - case Ident(Name name): - buf.append("Ident("); - append(buf, name); - break; - case Literal(scalac.atree.AConstant value): - buf.append("Literal(" + value); - break; - case TypeTerm(): - buf.append("TypeTerm("); - break; - case SingletonType(Tree ref): - buf.append("SingletonType("); - append(buf, ref, showType); - break; - case SelectFromType(Tree qualifier, Name selector): - buf.append("SelectFromType("); - append(buf, qualifier, showType); - buf.append(','); - append(buf, selector); - break; - case FunType(Tree[] argtpes, Tree restpe): - buf.append("FunType("); - append(buf, argtpes); - buf.append(','); - append(buf, restpe); - break; - case CompoundType(Tree[] parents, Tree[] refinements): - buf.append("CompoundType("); - append(buf, parents); - buf.append(','); - append(buf, refinements); - break; - case AppliedType(Tree tpe, Tree[] args): - buf.append("AppliedType("); - append(buf, tpe); - buf.append(','); - append(buf, args); - break; - case Try(Tree block, Tree catcher, Tree finalizer): - buf.append("Try("); - append(buf, block); - buf.append(','); - append(buf, catcher); - buf.append(','); - append(buf, finalizer); - break; - default: - buf.append(tree.getClass().getName() + "("); - } - buf.append(')'); - if (showType) buf.append(":" + tree.type); - } - - public static String showTree(Tree tree, boolean showType) { - StringBuffer buf = new StringBuffer(); - append(buf, tree, showType); - return buf.toString(); - } - - public static String showTree(Tree tree) { - return showTree(tree, false); - } - - public static String showTree(Tree[] trees, boolean showType) { - StringBuffer buf = new StringBuffer(); - append(buf, trees, showType); - return buf.toString(); - } - - public static String showTree(Tree[] trees) { - return showTree(trees, false); - } - - //######################################################################## -} - -/** This class implements a debugger for symbols. */ -public class SymbolDebugger implements Debugger { - - //######################################################################## - // Public Constants - - /** The unique instance of this class. */ - public static final SymbolDebugger object = new SymbolDebugger(); - - //######################################################################## - // Protected Constructors - - /** Initializes this instance. */ - protected SymbolDebugger() {} - - //######################################################################## - // Public Methods - - public boolean canAppend(Object object) { - return object instanceof Symbol; - } - - public void append(StringBuffer buffer, Object object) { - Symbol symbol = (Symbol)object; - if (!symbol.isNone() && !symbol.owner().isRoot() && !symbol.isRoot()) { - Debug.append(buffer, symbol.owner()); - buffer.append("."); - } - buffer.append(symbol.name); - if (Global.instance.uniqid) { - buffer.append('#'); - buffer.append(symbol.id); - } - if (symbol.isConstructor()) { - buffer.append('('); - buffer.append(symbol.constructorClass().name); - buffer.append(')'); - } - } - - //######################################################################## -} - -/** This class implements a debugger for scopes. */ -public class ScopeDebugger implements Debugger { - - //######################################################################## - // Public Constants - - /** The unique instance of this class. */ - public static final ScopeDebugger object = new ScopeDebugger(); - - //######################################################################## - // Protected Constructors - - /** Initializes this instance. */ - protected ScopeDebugger() {} - - //######################################################################## - // Public Methods - - public boolean canAppend(Object object) { - return object instanceof Scope; - } - - public void append(StringBuffer buffer, Object object) { - Scope scope = (Scope)object; - buffer.append('{'); - for (Scope.SymbolIterator i = scope.iterator(); i.hasNext();) { - Debug.append(buffer, i.next()); - if (i.hasNext()) buffer.append(','); - } - buffer.append('}'); - } - - //######################################################################## -} diff --git a/sources/scalac/util/EmptyPhase.java b/sources/scalac/util/EmptyPhase.java deleted file mode 100644 index 5600fc85b9..0000000000 --- a/sources/scalac/util/EmptyPhase.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; - -/** This class implements a phase that does nothing. */ -public class EmptyPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public EmptyPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - // do nothing - } - - //######################################################################## -} diff --git a/sources/scalac/util/FreshNameCreator.java b/sources/scalac/util/FreshNameCreator.java deleted file mode 100644 index 3675f359f0..0000000000 --- a/sources/scalac/util/FreshNameCreator.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.util.HashMap; - -public class FreshNameCreator { - - protected int counter = 0; - protected HashMap counters = new HashMap(); - - /** - * Create a fresh name with the given prefix. It is guaranteed - * that the returned name has never been returned by a previous - * call to this function with the same separator character (which - * has to be a non-digit). - */ - public Name newName(String prefix, char separator) { - prefix += separator; - Integer ival = (Integer)counters.get(prefix); - if (ival == null) - counters.put(prefix, ival = new Integer(0)); - else - counters.put(prefix, ival = new Integer(ival.intValue() + 1)); - return Name.fromString(prefix + ival); - } - - /** Same, with `$' as the separator character - */ - public Name newName(String prefix) { - return newName(prefix, '$'); - } - - /** Same, but with a name as prefix. The new name is a type - * (respectively, constructor) name if the prefix is one. - */ - public Name newName(Name prefixName, char separator) { - Name name = newName(prefixName.toString(), separator); - if (prefixName.isTypeName()) return name.toTypeName(); - else return name; - } - - /** Same, with `$' as the separator character - */ - public Name newName(Name prefix) { - return newName(prefix, '$'); - } - - public Name newName() { - return Name.fromString("$" + (counter++) + "$"); - } -} diff --git a/sources/scalac/util/Name.java b/sources/scalac/util/Name.java deleted file mode 100644 index af088d6f79..0000000000 --- a/sources/scalac/util/Name.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -/** This class implements the common part of TermName and TypeName. */ -public abstract class Name { - - //######################################################################## - // Public Fields - - /** The unique identifier */ - public final int index; - - //######################################################################## - // Private Fields - - /** The related term name */ - private final TermName term; - - /** The related type name (null if not yet created) */ - private TypeName type; - - //######################################################################## - // Protected Constructors - - /** Initializes this instance. */ - protected Name(int index, TermName term) { - this.index = index; - this.term = term == null ? (TermName)this : term; - this.type = term == null ? null : (TypeName)this; - } - - //######################################################################## - // Public Factories - - /** Returns the term name with given ASCII representation. */ - public static TermName fromAscii(byte[] bytes, int start, int count) { - return TermName.fromAscii(bytes, start, count); - } - - /** Returns the term name with given string representation. */ - public static TermName fromString(String string) { - return TermName.fromString(string); - } - - //######################################################################## - // Public Methods - - /** Is this name a variable identifier? */ - public final boolean isVariable() { - char first = charAt(0); - return (('a' <= first && first <= 'z') || first == '_') - && this != Names.false_ - && this != Names.true_ - && this != Names.null_; - } - - /** Is this name a term name? */ - public final boolean isTermName() { - return this == term; - } - - /** Is this name a type name? */ - public final boolean isTypeName() { - return this == type; - } - - /** Returns the term name with the same representation. */ - public final TermName toTermName() { - return term; - } - - /** Returns the type name with the same representation. */ - public final TypeName toTypeName() { - return type != null ? type : (type = new TypeName(term)); - } - - /** Returns the result of "toString().length()". */ - public final int length() { - return toString().length(); - } - - /** Returns the result of "toString().charAt(index)". */ - public final char charAt(int index) { - return toString().charAt(index); - } - - /** Returns the result of "toString().indexOf(ch)". */ - public final int indexOf(char ch) { - return toString().indexOf(ch); - } - - /** Returns the result of "toString().indexOf(ch, start)". */ - public final int indexOf(char ch, int start) { - return toString().indexOf(ch, start); - } - - /** Returns the result of "toString().lastIndexOf(ch)". */ - public final int lastIndexOf(char ch) { - return toString().lastIndexOf(ch); - } - - /** Returns the result of "toString().lastIndexOf(ch, start)". */ - public final int lastIndexOf(char ch, int start) { - return toString().lastIndexOf(ch, start); - } - - /** Returns the hash code of this name. */ - public final int hashCode() { - return index; - } - - /** Returns the string representation of this name. */ - public String toString() { - return term.toString(); - } - - /** - * Returns the ASCII representation of this name. The returned - * array is not a copy. Therefore, it is forbidden to modify it. - */ - public byte[] toAsciiUnsafe() { - return term.toAsciiUnsafe(); - } - - //######################################################################## -} diff --git a/sources/scalac/util/NameTransformer.java b/sources/scalac/util/NameTransformer.java deleted file mode 100644 index b04b665379..0000000000 --- a/sources/scalac/util/NameTransformer.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.util; - -/** A name transformer for replacing operator symbols in names by predefined - * names of the form $opname. - * - * @author Martin Odersky, Christine Roeckl - * @version 1.1 - */ -public class NameTransformer { - - public static String[] operatorName = new String[128]; - - static { - operatorName['~'] = "$tilde"; - operatorName['='] = "$eq"; - operatorName['<'] = "$less"; - operatorName['>'] = "$greater"; - operatorName['!'] = "$bang"; - operatorName['#'] = "$hash"; - operatorName['%'] = "$percent"; - operatorName['^'] = "$up"; - operatorName['&'] = "$amp"; - operatorName['|'] = "$bar"; - operatorName['*'] = "$times"; - operatorName['/'] = "$div"; - operatorName['+'] = "$plus"; - operatorName['-'] = "$minus"; - operatorName[':'] = "$colon"; - operatorName['\\']= "$bslash"; - } - - /** Replace operator symbols by corresponding "$op_name" in names. - */ - public static Name encode(Name name) { - String string = name.toString(); - StringBuffer buffer = null; - for (int i = 0; i < string.length(); i++) { - char c = string.charAt(i); - if (c < 128) { - String operator = operatorName[c]; - if (operator != null) { - if (buffer == null) { - int capacity = string.length() - 1 + operator.length(); - buffer = new StringBuffer(capacity); - buffer.append(string.substring(0, i)); - } - buffer.append(operator); - continue; - } - } - if (buffer != null) buffer.append(c); - } - return buffer == null ? name : Name.fromString(buffer.toString()); - } - - /** Replace "$op_name" by corresponding operator symbols in names. - */ - public static String decode(Name name) { - return decode(name.toString()); - } - public static String decode(String string) { - StringBuffer buffer = null; - for (int i = 0; i < string.length(); i++) { - char c = string.charAt(i); - if (c == '$') { - int index = -1; - int length = -1; // an operator may be a prefix of another one - for (int j = 0; j < operatorName.length; j++) { - String operator = operatorName[j]; - if (operator == null) continue; - if (operator.length() <= length) continue; - if (!string.startsWith(operator, i)) continue; - index = j; - length = operator.length(); - } - if (length >= 0) { - if (buffer == null) { - int capacity = string.length() - length + 1; - buffer = new StringBuffer(capacity); - buffer.append(string.substring(0, i)); - } - buffer.append((char)index); - i += length - 1; - continue; - } - } - if (buffer != null) buffer.append(c); - } - return buffer == null ? string : buffer.toString(); - } - -} diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java deleted file mode 100644 index 66a67f819c..0000000000 --- a/sources/scalac/util/Names.java +++ /dev/null @@ -1,268 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** -** $Id$ -\* */ -package scalac.util; - -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; -import scalac.symtab.ClassSymbol; - -public class Names { - - private static final SymbolNameWriter writer = - new SymbolNameWriter().setAllSeparators('$').setRootSeparator('\0'); - - private static final String ALIAS_PREFIX = "alias$"; - private static final String LOCAL_PREFIX = "local$"; - private static final String MIXIN_PREFIX = "mixin$"; - private static final String OUTER_PREFIX = "outer$"; - private static final String SUPER_PREFIX = "super$"; - private static final String ACCESS_PREFIX = "access$"; - private static final String TUPLE_FIELD_PREFIX = "_"; - private static final String TYPE_PREFIX = "type$"; - private static final String INSTANTIATE_PREFIX = "instantiate$"; - private static final String LAZYPARENTS_PREFIX = "LazyParents$"; - private static final String TYPECONSTRUCTOR_PREFIX = "tConstructor$"; - - public static Name ALIAS(ClassSymbol clasz) { - return Name.fromString(ALIAS_PREFIX + clasz.name).toTypeName(); - } - - public static Name LOCAL(Symbol clasz) { - return Name.fromString(LOCAL_PREFIX + clasz.name); - } - - public static Name MIXIN(Symbol member) { - Name name = Name.fromString(MIXIN_PREFIX + member.owner().name - + (member.isInitializer() ? INLINED_INITIALIZER : member.name)); - if (member.name.isTypeName()) name = name.toTypeName(); - return name; - } - - public static Name OUTER(Symbol constructor) { - if (constructor.isClass()) - return Name.fromString(OUTER_PREFIX + constructor.owner().name); - assert constructor.isConstructor(): Debug.show(constructor); - Symbol clasz = constructor.constructorClass(); - Symbol[] constructors = clasz.allConstructors().alternativeSymbols(); - int index = 0; - while (constructors[index] != constructor) index++; - String name = OUTER_PREFIX + index +"$"+ clasz.owner().name; - return Name.fromString(name); - } - - public static Name OUTER(Symbol constructor, Symbol member) { - Name name = Name.fromString(OUTER(constructor) + "$" + member.name); - if (member.name.isTypeName()) name = name.toTypeName(); - return name; - } - - public static Name ACCESS(Symbol member, boolean svper) { - assert member.isTerm() && member.owner().isClass(): Debug.show(member); - String prefix = svper ? ACCESS_PREFIX + SUPER_PREFIX : ACCESS_PREFIX; - return Name.fromString(writer.toString(prefix, member)); - } - - public static Name TUPLE_FIELD(int index) { - return Name.fromString(TUPLE_FIELD_PREFIX + index); - } - - public static Name TYPE(Symbol sym) { - return Name.fromString(TYPE_PREFIX + sym.name); - } - - public static Name INSTANTIATE(Symbol sym, boolean isStatic) { - return Name.fromString(INSTANTIATE_PREFIX - + sym.name - + (isStatic ? "$" : "")); - } - - public static Name LAZYPARENTS(Symbol clsSym) { - return Name.fromString(LAZYPARENTS_PREFIX + clsSym.name).toTypeName(); - } - - public static Name TYPECONSTRUCTOR(Symbol sym, boolean isStatic) { - return Name.fromString(TYPECONSTRUCTOR_PREFIX - + sym.name - + (isStatic ? "$" : "")); - } - - public static final Name ERROR = Name.fromString("<error>"); - public static final Name NOSYMBOL = Name.fromString("<none>"); - public static final Name EMPTY = Name.fromString(""); - public static final Name IMPORT_WILDCARD = Name.fromString("_"); - public static final Name PATTERN_WILDCARD = Name.fromString("_"); - public static final Name COMPOUND_NAME = Name.fromString("<ct>"); - public static final Name ANON_CLASS_NAME = Name.fromString("$anon"); - public static final Name ZERO = Name.fromString("<zero>"); - public static final Name STAR = Name.fromString("*"); - public static final Name ROOT = Name.fromString("<root>"); - - public static final Name CONSTRUCTOR = Name.fromString("<init>"); - public static final Name CLASS_CONSTRUCTOR = Name.fromString("<clinit>"); - public static final Name INITIALIZER = Name.fromString("<init>"); - public static final Name INLINED_INITIALIZER = Name.fromString("$init$"); - - public static final Name _EQ = encode("_="); - public static final Name MINUS = encode("-"); - public static final Name PLUS = encode("+"); - public static final Name TILDE = encode("~"); - public static final Name EQEQ = encode("=="); - public static final Name BANG = encode("!"); - public static final Name BANGEQ = encode("!="); - public static final Name BARBAR = encode("||"); - public static final Name AMPAMP = encode("&&"); - public static final Name COLONCOLON = encode("::"); - public static final Name PERCENT = encode("%"); - public static final Name PLUSEQ = encode("+="); - public static final Name MINUSEQ = encode("-="); - - public static final Name All = Name.fromString("All"); - public static final Name AllRef = Name.fromString("AllRef"); - public static final Name Any = Name.fromString("Any"); - public static final Name AnyVal = Name.fromString("AnyVal"); - public static final Name AnyRef = Name.fromString("AnyRef"); - public static final Name Array = Name.fromString("Array"); - public static final Name Byte = Name.fromString("Byte"); - public static final Name CaseClass = Name.fromString("CaseClass"); - public static final Name Catch = Name.fromString("Catch"); - public static final Name Char = Name.fromString("Char"); - public static final Name Boolean = Name.fromString("Boolean"); - public static final Name Do = Name.fromString("Do"); - public static final Name Double = Name.fromString("Double"); - public static final Name Element = Name.fromString("Element"); - public static final Name Finally = Name.fromString("Finally"); - public static final Name Float = Name.fromString("Float"); - public static final Name Function = Name.fromString("Function"); - public static final Name GetType = Name.fromString("GetType"); - public static final Name Int = Name.fromString("Int"); - public static final Name Labelled = Name.fromString("Labelled"); - public static final Name List = Name.fromString("List"); - public static final Name Long = Name.fromString("Long"); - public static final Name Nil = Name.fromString("Nil"); - public static final Name Object = Name.fromString("Object"); - public static final Name PartialFunction = Name.fromString("PartialFunction"); - public static final Name Predef = Name.fromString("Predef"); - public static final Name ScalaObject = Name.fromString("ScalaObject"); - public static final Name ScalaRunTime = Name.fromString("ScalaRunTime"); - public static final Name Seq = Name.fromString("Seq"); - public static final Name Short = Name.fromString("Short"); - public static final Name String = Name.fromString("String"); - public static final Name Symbol = Name.fromString("Symbol"); - public static final Name Text = Name.fromString("Text"); - public static final Name Throwable = Name.fromString("Throwable"); - public static final Name Try = Name.fromString("Try"); - public static final Name Tuple = Name.fromString("Tuple"); - public static final Name Type = Name.fromString("Type"); - public static final Name Tuple2 = Name.fromString("Tuple2"); - public static final Name Unit = Name.fromString("Unit"); - public static final Name While = Name.fromString("While"); - public static final Name apply = Name.fromString("apply"); - public static final Name array = Name.fromString("array"); - public static final Name asInstanceOf = Name.fromString("asInstanceOf"); - public static final Name asInstanceOfE = Name.fromString("asInstanceOf$erased"); - public static final Name box = Name.fromString("box"); - public static final Name caseArity = Name.fromString("caseArity"); - public static final Name caseElement = Name.fromString("caseElement"); - public static final Name cur = Name.fromString("cur"); // used in translation of automata - public static final Name cast = Name.fromString("cast"); - public static final Name clone = Name.fromString("clone"); - public static final Name coerce = Name.fromString("coerce"); - public static final Name defaultValue = Name.fromString("defaultValue"); - public static final Name elem = Name.fromString("elem"); - public static final Name elements = Name.fromString("elements"); - public static final Name emptyArray = Name.fromString("EMPTY_ARRAY"); - public static final Name eq = Name.fromString("eq"); - public static final Name equals = Name.fromString("equals"); - public static final Name fail = Name.fromString("fail"); - public static final Name false_ = Name.fromString("false"); - public static final Name filter = Name.fromString("filter"); - public static final Name finalize = Name.fromString("finalize"); - public static final Name flatmap = Name.fromString("flatMap"); - public static final Name foreach = Name.fromString("foreach"); - public static final Name force = Name.fromString("force"); - public static final Name functionOuter = Name.fromString("FUNCTION_OUTER"); - public static final Name get = Name.fromString("get"); - public static final Name getClass = Name.fromString("getClass"); - public static final Name getInstantiation = Name.fromString("getInstantiation"); - public static final Name getScalaType = Name.fromString("getScalaType"); - public static final Name isInstance = Name.fromString("isInstance"); - public static final Name hashCode = Name.fromString("hashCode"); - public static final Name hasNext = Name.fromString("hasNext"); - public static final Name head = Name.fromString("head"); - public static final Name isInstanceOf = Name.fromString("isInstanceOf"); - public static final Name isInstanceOfE = Name.fromString("isInstanceOf$erased"); - public static final Name isDefinedAt = Name.fromString("isDefinedAt"); - public static final Name isEmpty = Name.fromString("isEmpty"); - public static final Name instantiate = Name.fromString("instantiate"); - public static final Name java = Name.fromString("java"); - public static final Name javaRefArrayType = Name.fromString("javaRefArrayType"); - public static final Name javaArrayType = Name.fromString("javaArrayType"); - public static final Name javaClassType = Name.fromString("javaClassType"); - public static final Name lang = Name.fromString("lang"); - public static final Name length = Name.fromString("length"); - public static final Name _match = Name.fromString("match"); - public static final Name map = Name.fromString("map"); - public static final Name n = Name.fromString("n"); - public static final Name ne = Name.fromString("ne"); - public static final Name nobinding = Name.fromString("nobinding"); - public static final Name next = Name.fromString("next"); - public static final Name newArray = Name.fromString("newArray"); - public static final Name notify = Name.fromString("notify"); - public static final Name notifyAll = Name.fromString("notifyAll"); - public static final Name null_ = Name.fromString("null"); - public static final Name predef = Name.fromString("predef"); - public static final Name print = Name.fromString("print"); - public static final Name readResolve = Name.fromString("readResolve"); - public static final Name report = Name.fromString("report"); - public static final Name result = Name.fromString("$result"); - public static final Name runtime = Name.fromString("runtime"); - public static final Name scala = Name.fromString("scala"); - public static final Name setParents = Name.fromString("setParents"); - public static final Name synchronized_ = Name.fromString("synchronized"); - public static final Name tag = Name.fromString("$tag"); - public static final Name tail = Name.fromString("tail"); - public static final Name toString = Name.fromString("toString"); - public static final Name that = Name.fromString("that"); - public static final Name that1 = Name.fromString("that1"); - public static final Name this_ = Name.fromString("this"); - public static final Name throw_ = Name.fromString("throw"); - public static final Name true_ = Name.fromString("true"); - public static final Name update = Name.fromString("update"); - public static final Name view = Name.fromString("view"); - public static final Name wait = Name.fromString("wait"); - public static final Name isNonTrivialInstance = Name.fromString("isNonTrivialInstance"); - public static final Name xml = Name.fromString("xml"); - - - public static final Name - ZNOT = encode("!"), - ZAND = encode("&&"), - ZOR = encode("||"), - NOT = encode("~"), - ADD = encode("+"), - SUB = encode("-"), - MUL = encode("*"), - DIV = encode("/"), - MOD = encode("%"), - EQ = encode("=="), - NE = encode("!="), - LT = encode("<"), - LE = encode("<="), - GT = encode(">"), - GE = encode(">="), - OR = encode("|"), - XOR = encode("^"), - AND = encode("&"), - LSL = encode("<<"), - LSR = encode(">>>"), - ASR = encode(">>"); - - private static Name encode(String string) { - return NameTransformer.encode(Name.fromString(string)); - } -} diff --git a/sources/scalac/util/OptionParser.java b/sources/scalac/util/OptionParser.java deleted file mode 100644 index 9521ca388e..0000000000 --- a/sources/scalac/util/OptionParser.java +++ /dev/null @@ -1,541 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import scala.tools.util.Position; -import scala.tools.util.Reporter; - -import java.text.Format; -import java.text.MessageFormat; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.StringTokenizer; - -import scalac.PhaseDescriptor; -//import scalac.optimizer.OptimizePhase; - -public class CommandParser { - - private final String product; - private final String version; - private final String syntax; - private final Reporter reporter; - private final List/*<ArgumentParser>*/ parsers; - - public CommandParser(String product, String version, String syntax, - Reporter reporter) - { - this.product = product; - this.version = version; - this.syntax = syntax; - this.reporter = reporter; - this.parsers = new ArrayList(); - } - - public String product() { - return product; - } - - public String version() { - return version; - } - - public String syntax() { - return syntax; - } - - public Reporter reporter() { - return reporter; - } - - public boolean add(ArgumentParser parser) { - return parsers.add(parser); - } - - public void add(int index, ArgumentParser parser) { - parsers.add(index, parser); - } - - public boolean remove(ArgumentParser parser) { - return parsers.remove(parser); - } - - public List parsers() { - return parsers; - } - - public boolean parse(String[] args) { - int errors = reporter.errors(); - for (int i = 0; i < args.length; ) { - for (int j = 0; j < parsers.size(); j++) { - ArgumentParser parser = (ArgumentParser)parsers.get(j); - if (parser.matches(args, i)) { - i = parser.consume(args, i); - break; - } - } - } - return reporter.errors() == errors; - } - - public String getHelpMessage() { - Format format = new MessageFormat(" {0}\t {1}"); - List options = new ArrayList(parsers.size()); - for (int i = 0; i < parsers.size(); i++) { - if (!(parsers.get(i) instanceof OptionParser)) continue; - OptionParser parser = (OptionParser)parsers.get(i); - String option = parser.getHelpMessage(format); - if (option != null) options.add(option); - } - StringBuffer buffer = new StringBuffer(); - buffer.append("usage: ").append(product()); - if (options.size() > 0) buffer.append(" <options>"); - if (syntax != null) buffer.append(' ').append(syntax); - buffer.append(Strings.EOL); - if (options.size() > 0) { - buffer.append("where possible options include:"); - buffer.append(Strings.EOL); - buffer.append(Strings.format(options)); - } - return buffer.toString(); - } - - public void error(String message) { - reporter.error(new Position(product), message); - } - - public void warning(String message) { - reporter.warning(new Position(product), message); - } -} - -public abstract class ArgumentParser { - - public final CommandParser command; - - public ArgumentParser(CommandParser command) { - this.command = command; - } - - public abstract boolean matches(String[] args, int index); - public abstract int consume(String[] args, int index); - -} - -public class UnknownArgumentParser extends ArgumentParser { - - public UnknownArgumentParser(CommandParser command) { - super(command); - } - - public boolean matches(String[] args, int index) { - return true; - } - - public int consume(String[] args, int index) { - command.error("don't known what to do with '" + args[index] + "'"); - return index + 1; - } -} - -public class ScalaFileArgumentParser extends ArgumentParser { - - public final List list; - - public ScalaFileArgumentParser(CommandParser command) { - super(command); - this.list = new ArrayList(); - } - - public boolean matches(String[] args, int index) { - return args[index].endsWith(".scala"); - } - - public int consume(String[] args, int index) { - list.add(args[index]); - return index + 1; - } - - public String[] toArray() { - return (String[])list.toArray(new String[list.size()]); - } -} - -public class ScalaProgramArgumentParser extends ArgumentParser { - - public String main; - public String[] args; - - public ScalaProgramArgumentParser(CommandParser command) { - super(command); - } - - public boolean matches(String[] args, int index) { - return args[index].equals("--"); - } - - public int consume(String[] args, int index) { - if (index + 1 < args.length) { - this.main = args[index + 1]; - this.args = new String[args.length - index - 2]; - System.arraycopy(args, index + 2, this.args, 0, this.args.length); - return args.length; - } else { - command.error("option --: missing module name"); - return args.length; - } - } -} - -public abstract class OptionParser extends ArgumentParser { - - public final String option; - public final String description; - - public OptionParser(CommandParser command, String option, - String description) - { - super(command); - this.option = option; - this.description = description; - } - - public String getHelpSyntax() { - return "-" + option; - } - - public String getHelpDescription() { - return description; - } - - public void getHelpMessageArgs(List args) { - args.add(getHelpSyntax()); - args.add(getHelpDescription()); - } - - public String getHelpMessage(Format format) { - if (description == null) return null; - List args = new ArrayList(); - getHelpMessageArgs(args); - return format.format(args.toArray()); - } - - public void error(String message) { - command.error("option -" + option + ": " + message); - } - - public void warning(String message) { - command.warning("option -" + option + ": " + message); - } -} -/* -public class OptimizeOptionParser extends OptionParser { - - private final OptimizePhase optimizer; - public boolean optimize; - - public OptimizeOptionParser(CommandParser command, - String option, String description, OptimizePhase optimizer) - { - super(command, option, description); - this.optimizer = optimizer; - this.optimize = false; - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-" + option); - } - - public int consume(String[] args, int index) { - optimizer.setOptions(args[index].substring(1 + option.length())); - optimize = true; - return index + 1; - } - - public String getHelpSyntax() { - return super.getHelpSyntax() + "[:<options>]"; - } -} -*/ -public class VersionOptionParser extends OptionParser { - - private final String version; - - public VersionOptionParser(CommandParser command, - String option, String description, String version) - { - super(command, option, description); - this.version = version; - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-" + option); - } - - public int consume(String[] args, int index) { - System.out.println(version); - System.exit(0); - return index + 1; - } -} - -public class HelpOptionParser extends OptionParser { - - public HelpOptionParser(CommandParser command, - String option, String description) - { - super(command, option, description); - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-?") || - args[index].equals("-" + option) || - args[index].equals("--" + option); - } - - public int consume(String[] args, int index) { - System.out.println(command.getHelpMessage()); - System.exit(0); - return index + 1; - } - - public String getHelpSyntax() { - return "-? " + super.getHelpSyntax(); - } -} - -public class UnknownOptionParser extends OptionParser { - - public UnknownOptionParser(CommandParser command) { - super(command, "", null); - } - - public boolean matches(String[] args, int index) { - return args[index].startsWith("-"); - } - - public int consume(String[] args, int index) { - command.error("unknown option " + args[index]); - return index + 1; - } -} - -public class BooleanOptionParser extends OptionParser { - - public boolean value; - - public BooleanOptionParser(CommandParser command, - String option, String description, boolean value) - { - super(command, option, description); - this.value = value; - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-" + option); - } - - public int consume(String[] args, int index) { - value = true; - return index + 1; - } -} - -public class StringOptionParser extends OptionParser { - - public String value; - public String argument; - - public StringOptionParser(CommandParser command, - String option, String description, String argument, String value) - { - super(command, option, description); - this.argument = argument; - this.value = value; - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-" + option); - } - - public int consume(String[] args, int index) { - if (index + 1 < args.length) { - value = args[index + 1]; - return index + 2; - } else { - error("missing argument"); - return index + 1; - } - } - - public String getHelpSyntax() { - String syntax = super.getHelpSyntax(); - if (argument != null) syntax = syntax + " <" + argument + ">"; - return syntax; - } -} - -public class PhaseSetOptionParser extends OptionParser { - - private final PhaseDescriptor[] phases; - private final int flag; - private final PrefixMatcher matcher; - - public PhaseSetOptionParser(CommandParser command, - String option, String description, PhaseDescriptor[] phases, int flag) - { - super(command, option, description); - this.phases = phases; - this.flag = flag; - this.matcher = new PrefixMatcher(); - for (int i = 0; i < phases.length; i++) { - PhaseDescriptor phase = phases[i]; - matcher.insert(phase.name(), phase, phase.description()); - } - } - - public boolean matches(String[] args, int index) { - return args[index].startsWith("-" + option + ":"); - } - - public int consume(String[] args, int index) { - StringTokenizer tokens = new StringTokenizer( - args[index].substring(option.length() + 2), ","); - while (tokens.hasMoreTokens()) consumePhase(tokens.nextToken()); - return index + 1; - } - - public void consumePhase(String token) { - if (token.equals("all")) { - for (int i = 0; i < phases.length; i++) - phases[i].addFlag(flag, false); - return; - } - PhaseDescriptor phase = lookup(getPhaseName(token)); - if (phase != null) { - boolean before = getBeforeFlag(token); - boolean after = getAfterFlag(token) || !before; - if (before) phase.addFlag(flag, true); - if (after) phase.addFlag(flag, false); - } - } - - public PhaseDescriptor lookup(String name) { - if (name.length() == 0) { - error("illegal zero-length phase name"); - return null; - } - PrefixMatcher.Entry[] entries = matcher.lookup(name); - if (entries.length == 1) return (PhaseDescriptor)entries[0].value; - error(matcher.getErrorMessage(name, entries, "phase name")); - return null; - } - - public boolean getBeforeFlag(String token) { - for (int i = token.length(); 0 < i--; ) { - switch (token.charAt(i)) { - case '-': return true; - case '+': continue; - default : return false; - } - } - return false; - } - - public boolean getAfterFlag(String token) { - for (int i = token.length(); 0 < i--; ) { - switch (token.charAt(i)) { - case '-': continue; - case '+': return true; - default : return false; - } - } - return false; - } - - public String getPhaseName(String token) { - for (int i = token.length(); 0 < i--; ) { - switch (token.charAt(i)) { - case '-': continue; - case '+': continue; - default : return token.substring(0, i + 1); - } - } - return ""; - } - - public String getHelpSyntax() { - return super.getHelpSyntax() + ":<phases>"; - } -} - -public class PrintOptionParser extends PhaseSetOptionParser { - - public boolean tokens; - - public PrintOptionParser(CommandParser command, - String option, String description, PhaseDescriptor[] phases, int flag) - { - super(command, option, description, phases, flag); - this.tokens = false; - } - - public void consumePhase(String token) { - if ("tokens".equals(token)) - tokens = true; - else - super.consumePhase(token); - } - -} - -public class ChoiceOptionParser extends OptionParser { - - public final String argument; - public final String[] choices; - - public String value; - - public ChoiceOptionParser(CommandParser command, - String option, String description, String argument, String[] choices, - String value) - { - super(command, option, description); - this.argument = argument; - this.choices = choices; - this.value = value; - } - - public boolean matches(String[] args, int index) { - return args[index].startsWith("-" + option + ":"); - } - - public int consume(String[] args, int index) { - String choice = args[index].substring(option.length() + 2); - boolean found = false; - for (int i = 0; i < choices.length; i++) { - if (choices[i].equals(choice)) { found = true; break; } - } - if (found) { - value = choice; - } else if (choice.length() > 0) { - error("unknown " + argument + " '" + choice + "'"); - } else { - error("missing " + argument); - } - return index + 1; - } - - public String getHelpSyntax() { - String syntax = super.getHelpSyntax(); - if (argument != null) syntax = syntax + ":<" + argument + ">"; - return syntax; - } -} diff --git a/sources/scalac/util/PrefixMatcher.java b/sources/scalac/util/PrefixMatcher.java deleted file mode 100644 index 1b0acd8d7a..0000000000 --- a/sources/scalac/util/PrefixMatcher.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; - -public class PrefixMatcher { - - public static class Entry { - - private Entry prev; - private Entry next; - - public final String key; - public final Object value; - public final String argument; - public final String description; - - public Entry(String key, Object value, String argument, - String description) - { - this.key = key; - this.value = value; - this.argument = argument; - this.description = description; - } - } - - private final Map entries; - private Entry first; - private Entry last; - - public PrefixMatcher() { - this.entries = new HashMap(); - } - - public void insert(String key, Object value) { - insert(key, value, null, null); - } - - public void insert(String key, Object value, String description) { - insert(key, value, null, description); - } - - public void insert(String key, Object value, String argument, - String description) - { - assert key != null && !entries.containsKey(key) : key; - Entry entry = new Entry(key, value, argument, description); - if (first == null) { - first = last = entry; - } else { - last.next = entry; - entry.prev = last; - last = entry; - } - entries.put(key, entry); - } - - public Entry[] lookup(String key) { - Object value = entries.get(key); - if (value != null) return new Entry[] { (Entry)value }; - List list = new ArrayList(); - for (Entry i = first; i != null; i = i.next) { - if (i.key.startsWith(key)) list.add(i); - } - return (Entry[])list.toArray(new Entry[list.size()]); - } - - public String getErrorMessage(String key, Entry[] entries, String what) { - switch (entries.length) { - case 0: - return "unknown " + what + " '" + key + "'"; - case 1: - return null; - case 2: - return "ambigous " + what + " '" + key + "', both '" + - entries[0].key + "' and '" + entries[1].key + "' match"; - default: - StringBuffer buffer = new StringBuffer(); - buffer.append("ambigous ").append(what); - buffer.append(" '").append(key).append("'"); - for (int i = 0; i < entries.length; i++) { - buffer.append(i < entries.length - 1 ? ", " : " and "); - buffer.append('\'').append(entries[i].key).append('\''); - } - buffer.append(" match"); - return buffer.toString(); - } - } - - public List getHelpStrings(String separator1, String separator2) { - List strings = new ArrayList(); - for (Entry entry = first; entry != null; entry = entry.next) { - if (entry.description != null) - if (entry.argument != null) - strings.add(entry.key + separator1 + entry.argument + - separator2 + entry.description); - else - strings.add(entry.key + separator2 + entry.description); - } - return strings; - } - -} diff --git a/sources/scalac/util/SourceRepresentation.java b/sources/scalac/util/SourceRepresentation.java deleted file mode 100644 index 83c1372769..0000000000 --- a/sources/scalac/util/SourceRepresentation.java +++ /dev/null @@ -1,227 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.io.File; - -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; - -public final class SourceRepresentation { - - /** The file name writer */ - private static SymbolNameWriter fileNameWriter = new SymbolNameWriter() - .setAllSeparators(File.separatorChar) - .setRootSeparator('\0'); - - public static int digit2int(char ch, int base) { - if ('0' <= ch && ch <= '9' && ch < '0' + base) - return ch - '0'; - else if ('A' <= ch && ch < 'A' + base - 10) - return ch - 'A' + 10; - else if ('a' <= ch && ch < 'a' + base - 10) - return ch - 'a' + 10; - else - return -1; - } - - public static byte int2digit(int x) { - if (x <= 9) - return (byte)(x + '0'); - else - return (byte)(x - 10 + 'A'); - } - -/* the next 4 functions convert between three fundamental name - * representations: - * - string each character 16 bit, - * - source characters outside 0..127 are represented by - * unicode escapes, \ u X X X X - * - ascii characters outside 0..127 are represented by two or three - * byte sequences with high bit set (as in class file format). - */ - -/** convert source bytes in source[offset..offset+len-1] to ascii. - */ - public static int source2ascii(byte source[], int offset, int len, byte ascii[]) { - int j = 0; - int i = 0; - while (i < len) { - if (source[offset + i] == '\\' && i + 1 < len) { - i++; - switch (source[offset + i]) { - case 'n': - ascii[j++] = (byte)'\n'; i++; continue; - case 't': - ascii[j++] = (byte)'\t'; i++; continue; - case 'b': - ascii[j++] = (byte)'\b'; i++; continue; - case 'r': - ascii[j++] = (byte)'\r'; i++; continue; - case 'f': - ascii[j++] = (byte)'\f'; i++; continue; - case 'u': - if (i + 4 < len) { - int code = 0; - int k = 1; - int d = 0; - while (k <= 4 && d >= 0) { - // !!! (char) - d = digit2int((char)source[offset + i + k], 16); - code = code * 16 + d; - k++; - } - if (d >= 0) { - if (code <= 0x7F) - ascii[j++] = (byte)code; - else - if (code <= 0x3FF) { - ascii[j++] = (byte)(0xC0 | (code >> 6)); - ascii[j++] = (byte)(0x80 | (code & 0x3F)); - } else { - ascii[j++] = (byte)(0xE0 | (code >> 12)); - ascii[j++] = (byte)(0x80 | - ((code >> 6) & 0x3F)); - ascii[j++] = (byte)(0x80 | (code & 0x3F)); - } - i = i + 5; - continue; - } - } - } - } - byte b = source[offset + i++]; - if (b >= 0) - ascii[j++] = b; - else { - ascii[j++] = (byte)(0xC0 | ((b >> 6) & 0x3)); - ascii[j++] = (byte)(0x80 | (b & 0x3F)); - } - } - return j; - } - -/** convert ascii bytes in ascii[offset..offset+len-1] to a string - */ - public static String ascii2string(byte ascii[], int offset, int len) { - char cs[] = new char[len]; - int i = offset; - int j = 0; - len += offset; - while (i < len) { - int b = ascii[i++] & 0xFF; - if (b >= 0xE0) { - b = ((b & 0x0F) << 12) | (ascii[i++] & 0x3F) << 6; - b = b | (ascii[i++] & 0x3F); - } - else - if (b >= 0xC0) - b = ((b & 0x1F) << 6) | (ascii[i++] & 0x3F); - cs[j++] = (char)b; - } - return new String(cs, 0, j); - } - -/** convert string to array of source bytes - */ - public static byte[] string2source(String s) { - byte[] source = new byte[s.length() * 6]; - int j = 0; - for (int i = 0; i < s.length(); i++) { - char ch = s.charAt(i); - switch (ch) { - case '\n': - source[j++] = (byte)'\\'; - source[j++] = (byte)'n'; - break; - case '\t': - source[j++] = (byte)'\\'; - source[j++] = (byte)'t'; - break; - case '\b': - source[j++] = (byte)'\\'; - source[j++] = (byte)'b'; - break; - case '\r': - source[j++] = (byte)'\\'; - source[j++] = (byte)'r'; - break; - case '\f': - source[j++] = (byte)'\\'; - source[j++] = (byte)'f'; - break; - case '\"': - source[j++] = (byte)'\\'; - source[j++] = (byte)'\"'; - break; - case '\'': - source[j++] = (byte)'\\'; - source[j++] = (byte)'\''; - break; - case '\\': - source[j++] = (byte)'\\'; - source[j++] = (byte)'\\'; - break; - default: - if ((' ' <= ch) && (ch <= 127)) - source[j++] = (byte)ch; - else { - source[j++] = (byte)'\\'; - source[j++] = (byte)'u'; - source[j++] = int2digit((ch >> 12) & 0xF); - source[j++] = int2digit((ch >> 8) & 0xF); - source[j++] = int2digit((ch >> 4) & 0xF); - source[j++] = int2digit(ch & 0xF); - } - } - } - byte[] res = new byte[j]; - System.arraycopy(source, 0, res, 0, j); - return res; - } - -/** convert string to array of ascii bytes - */ - public static byte[] string2ascii(String s) { - byte[] source = string2source(s); - byte[] ascii = new byte[source.length * 2]; - int alen = source2ascii(source, 0, source.length, ascii); - byte[] res = new byte[alen]; - System.arraycopy(ascii, 0, res, 0, alen); - return res; - } - -/** escape all characters outside 32..127 in string s - */ - public static String escape(String s) { - try { - return new String(string2source(s), "8859_1"); - } catch (java.io.UnsupportedEncodingException e) { - throw new InternalError(e.getMessage()); - } - } - -/** escape character c, if outside 32..127. - */ - public static String escape(char c) { - char[] s = {c}; - return escape(new String(s)); - } - - /** - * Returns the external file name with given suffix associated to - * given class. The file name use File.separatorChar as file - * separator. - */ - public static String externalizeFileName(Symbol clasz, String suffix) { - assert clasz.isClassType(): Debug.show(clasz); - return fileNameWriter.toString(clasz, suffix); - } - -} diff --git a/sources/scalac/util/Strings.java b/sources/scalac/util/Strings.java deleted file mode 100644 index 8d5c1d85c5..0000000000 --- a/sources/scalac/util/Strings.java +++ /dev/null @@ -1,102 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; - -public abstract class Strings { - - //######################################################################## - // Strings constants - - final public static String[] EMPTY_ARRAY = new String[0]; - - //######################################################################## - // Strings interface - - /** The line separator */ - public static String EOL = System.getProperty("line.separator", "\n"); - - /** Returns a string where all tabs have been replaced by white - * spaces to make the corresponding fields the same width. - */ - public static String format(List strings) { - List[] lines = new List[strings.size()]; - List widths = new ArrayList(); - int height = 0; - for (Iterator iterator = strings.iterator(); iterator.hasNext(); ) { - String string = (String)iterator.next(); - List line = lines[height++] = new ArrayList(); - for (int last = 0; last < string.length(); ) { - int next = string.indexOf('\t', last); - if (next < 0) next = string.length(); - String substring = string.substring(last, next); - int index = line.size(); - if (index == widths.size()) widths.add(new Integer(0)); - int width = ((Integer)widths.get(index)).intValue(); - widths.set( - index, new Integer(Math.max(width, substring.length()))); - line.add(substring); - last = next + 1; - } - } - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < lines.length; i++) { - List line = lines[i]; - for (int j = 0; true; j++) { - String string = (String)line.get(j); - buffer.append(string); - if (j == line.size() - 1) break; - int width = ((Integer)widths.get(j)).intValue(); - for (int k = string.length(); k<width; k++) buffer.append(' '); - } - buffer.append(EOL); - } - return buffer.toString(); - } - - /** Returns the first char of the string or -1 if the string is empty. */ - public static int firstChar(String string) { - return string.length() == 0 ? -1 : string.charAt(0); - } - - /** Returns the last char of the string or -1 if the string is empty. */ - public static int lastChar(String string) { - return string.length() == 0 ? -1 : string.charAt(string.length() - 1); - } - - /** Returns a copy of the string, with leading whitespace omitted. */ - public static String trimLeading(String string) { - for (int i = 0; i < string.length(); i++) - if (string.charAt(i) > ' ') return string.substring(i); - return ""; - } - - /** Returns a copy of the string, with trailing whitespace omitted. */ - public static String trimTrailing(String string) { - for (int i = string.length() - 1; i >= 0; i--) - if (string.charAt(i) > ' ') return string.substring(0, i + 1); - return ""; - } - - /** Returns the stack trace of the exception */ - public static String stackTrace(Throwable exception) { - StringWriter buffer = new StringWriter(); - PrintWriter writer = new PrintWriter(buffer); - exception.printStackTrace(writer); - writer.close(); - return buffer.toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/util/TermName.java b/sources/scalac/util/TermName.java deleted file mode 100644 index 8215a8ce2e..0000000000 --- a/sources/scalac/util/TermName.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.util.HashMap; - -/** Instances of this class represent term names. */ -public final class TermName extends Name { - - //######################################################################## - // Private Variables - - /** Hashtable from string representation to term names. */ - private static HashMap/*<String,TermName>*/ strings = new HashMap(); - - /** Hashtable from ASCII representation to term names. */ - private static TermName[] asciis = new TermName[0x00008000]; - - //######################################################################## - // Private Fields - - /** The string representation */ - private final String string; - - /** The ASCII representation (null if not yet computed) */ - private byte[] ascii; - - /** The next name stored in the same bucket of the ASCII table */ - private TermName next; - - //######################################################################## - // Private Constructors - - /** Initializes this instance. */ - private TermName(String string) { - super(2 * strings.size(), null); - this.string = string; - strings.put(string, this); - } - - //######################################################################## - // Public Factories - - /** Returns the term name with given ASCII representation. */ - public static TermName fromAscii(byte[] bytes, int start, int count) { - int index = hashValue(bytes, start, count) & (asciis.length - 1); - for (TermName name = asciis[index]; name != null; name = name.next) - if (name.equals(bytes, start, count)) return name; - TermName name = fromString( - SourceRepresentation.ascii2string(bytes, start, count)); - byte[] ascii = new byte[count]; - for (int i = 0; i < ascii.length; i++) ascii[i] = bytes[start + i]; - name.setAscii(ascii, index); - return name; - } - - /** Returns the term name with given string representation. */ - public static TermName fromString(String string) { - Object value = strings.get(string); - return value != null ? (TermName)value : new TermName(string); - } - - //######################################################################## - // Public Methods - - /** Returns the string representation of this name. */ - public String toString() { - return string; - } - - /** - * Returns the ASCII representation of this name. The returned - * array is not a copy. Therefore, it is forbidden to modify it. - */ - public byte[] toAsciiUnsafe() { - if (ascii == null) { - byte[] ascii = SourceRepresentation.string2ascii(string); - int index = hashValue(ascii, 0, ascii.length) & (asciis.length-1); - setAscii(ascii, index); - } - return ascii; - } - - //######################################################################## - // Private Methods & Functions - - /** Sets the ASCII representation to given one. */ - private void setAscii(byte[] ascii, int index) { - assert this.ascii == null: this; - this.ascii = ascii; - this.next = asciis[index]; - asciis[index] = this; - } - - /** Is this name's ASCII representations equal to given one? */ - private boolean equals(byte[] bytes, int start, int count) { - if (ascii.length != count) return false; - for (int i = 0; i < count; i++) - if (ascii[i] != bytes[start + i]) return false; - return true; - } - - /** Returns the hash code of the ASCII representation. */ - private static int hashValue(byte[] bytes, int start, int count) { - if (count <= 0) return 0; - return count * (41 * 41 * 41) - + bytes[start] * (41 * 41) - + bytes[start + count - 1] * 41 - + bytes[start + (count >> 1)]; - } - - //######################################################################## -} diff --git a/sources/scalac/util/TypeName.java b/sources/scalac/util/TypeName.java deleted file mode 100644 index cfe3b5193f..0000000000 --- a/sources/scalac/util/TypeName.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -/** Instances of this class represent type names. */ -public final class TypeName extends Name { - - //######################################################################## - // Protected Constructors - - /** Initializes this instance. */ - protected TypeName(TermName term) { - super(term.index + 1, term); - } - - //######################################################################## - // Public Factories - - /** Returns the type name with given ASCII representation. */ - public static TypeName fromAscii(byte[] bytes, int start, int count) { - return TermName.fromAscii(bytes, start, count).toTypeName(); - } - - /** Returns the type name with given string representation. */ - public static TypeName fromString(String string) { - return TermName.fromString(string).toTypeName(); - } - - //######################################################################## -} diff --git a/sources/scalac/util/TypeNames.java b/sources/scalac/util/TypeNames.java deleted file mode 100644 index 9f7fea1144..0000000000 --- a/sources/scalac/util/TypeNames.java +++ /dev/null @@ -1,16 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -public class TypeNames { - - public static final Name EMPTY = Names.EMPTY.toTypeName(); - public static final Name WILDCARD_STAR = Name.fromString("_*").toTypeName(); - -} |