summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-03-09 16:31:15 +0000
committerpaltherr <paltherr@epfl.ch>2004-03-09 16:31:15 +0000
commit829ff49f1cff21b98e2b9cd55ea5c5d3c7d4b4b3 (patch)
tree91191a653f3eb56cf88d8ddcdf8c90ed42ca2906
parentbf4d9f29a601a7a257da8fc666052889c45ae16e (diff)
downloadscala-829ff49f1cff21b98e2b9cd55ea5c5d3c7d4b4b3.tar.gz
scala-829ff49f1cff21b98e2b9cd55ea5c5d3c7d4b4b3.tar.bz2
scala-829ff49f1cff21b98e2b9cd55ea5c5d3c7d4b4b3.zip
- Added class scalac.symtab.SymbolLoader
-rw-r--r--config/list/compiler.lst1
-rw-r--r--sources/scalac/symtab/SymbolLoader.java144
2 files changed, 145 insertions, 0 deletions
diff --git a/config/list/compiler.lst b/config/list/compiler.lst
index 82ca8d1ace..63e748a5a7 100644
--- a/config/list/compiler.lst
+++ b/config/list/compiler.lst
@@ -95,6 +95,7 @@ symtab/SymSet.java
symtab/Symbol.java
symtab/SymbolCloner.java
symtab/SymbolComparator.java
+symtab/SymbolLoader.java
symtab/SymbolNameWriter.java
symtab/SymbolSubstTypeMap.java
symtab/SymbolTablePrinter.java
diff --git a/sources/scalac/symtab/SymbolLoader.java b/sources/scalac/symtab/SymbolLoader.java
new file mode 100644
index 0000000000..cb3907dbca
--- /dev/null
+++ b/sources/scalac/symtab/SymbolLoader.java
@@ -0,0 +1,144 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ 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 symbol. More precisely, it completes all related
+ * symbols of the main class of the symbol. It is guaranteed that
+ * after this method call all these symbols are initialized (or at
+ * least that their info does not contain this lazy type).
+ *
+ * The main class of a symbol is:
+ * - the main class of the constructed class, if it's a
+ * constructor,
+ * - the main class of the module class, if it's a module,
+ * - the dual class, if it's a dual module class,
+ * - itself if it's a non-dual class or a non-module class,
+ * - undefined otherwise.
+ *
+ * The related symbols of a class include:
+ * - the class itself,
+ * - its constructor (symbol returned by allConstructors()),
+ * - its module, if it has one,
+ * - the related symbols of its dual class, if it's dual
+ * non-module class.
+ */
+ public final void complete(Symbol symbol) {
+ Symbol clasz = getMainClass(symbol);
+ try {
+ long start = System.currentTimeMillis();
+ Phase phase = global.currentPhase;
+ global.currentPhase = global.PHASE.ANALYZER.phase();
+ String source = doComplete(clasz);
+ global.currentPhase = phase;
+ long end = System.currentTimeMillis();
+ global.operation("loaded " + source + " in " + (end-start) + "ms");
+ checkValidity(clasz, source, symbol);
+ } catch (IOException exception) {
+ 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);
+ }
+ initializeAll(clasz);
+ }
+
+ //########################################################################
+ // 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 main class (see also method complete).
+ */
+ protected abstract String doComplete(Symbol clasz) throws IOException;
+
+ //########################################################################
+ // Private Methods
+
+ /** Returns the main class of the symbol (see method complete). */
+ private Symbol getMainClass(Symbol symbol) {
+ if (symbol.isConstructor())
+ return getMainClass(symbol.constructorClass());
+ if (symbol.isModule())
+ return getMainClass(symbol.moduleClass());
+ assert symbol.isClassType(): Debug.show(symbol);
+ if (!symbol.isModuleClass()) return symbol;
+ return symbol.dualClass().isNone() ? symbol : symbol.dualClass();
+ }
+
+ /**
+ * Checks that at least the class or its dual class have been
+ * initialized and signals an error otherwise.
+ */
+ private void checkValidity(Symbol clasz, String source, Symbol s) {
+ if (clasz.rawInfo() != this) return;
+ String what;
+ if (clasz.dualClass().isNone()) {
+ what = "does not define " + clasz;
+ } else {
+ if (clasz.dualClass().rawInfo() != this) return;
+ Symbol module = clasz.dualClass().module();
+ what = "defines neither " + clasz + " nor " + module;
+ }
+ global.error(source + " " + what);
+ }
+
+ /**
+ * Initializes all related symbols of the class whose info is this
+ * instance (see also method complete).
+ */
+ private void initializeAll(Symbol clasz) {
+ initializeOne(clasz);
+ initializeOne(clasz.allConstructors());
+ if (clasz.isModuleClass()) initializeOne(clasz.module());
+ else if (!clasz.dualClass().isNone()) initializeAll(clasz.dualClass());
+ }
+
+ /** Initializes the symbol if its info is this instance. */
+ private void initializeOne(Symbol symbol) {
+ if (symbol.rawInfo() != this) return;
+ symbol.setInfo(symbol.isModule() ? Type.NoType : Type.ErrorType);
+ if (symbol.isConstructor()) symbol.flags |= Modifiers.PRIVATE;
+ }
+
+ //########################################################################
+}