Package anvil.script.statements

Source Code of anvil.script.statements.ModuleStatement

/*
* $Id: ModuleStatement.java,v 1.4 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.script.statements;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Calendar;
import java.util.HashSet;
import java.util.HashMap;
import anvil.ForgingException;
import anvil.java.util.BindingEnumeration;
import anvil.core.Any;
import anvil.core.AnyString;
import anvil.core.Array;
import anvil.core.Modules;
import anvil.core.runtime.AnyFunction;
import anvil.ErrorListener;
import anvil.Location;
import anvil.Log;
import anvil.codec.Code;
import anvil.codec.ClassRoom;
import anvil.codec.Field;
import anvil.codec.Method;
import anvil.codec.CodecConstants;
import anvil.codec.ConstantPool;
import anvil.doc.Doc;
import anvil.doc.DocParser;
import anvil.parser.Tag;
import anvil.ErrorListener;
import anvil.script.ClassType;
import anvil.script.CompilableFunction;
import anvil.script.compiler.ByteCompiler;
import anvil.script.Context;
import anvil.script.Type;
import anvil.script.Function;
import anvil.script.Dependency;
import anvil.script.Import;
import anvil.script.InterfaceType;
import anvil.script.Namespace;
import anvil.script.NamespaceType;
import anvil.script.parser.TemplateParser;
import anvil.script.Scope;
import anvil.script.Module;
import anvil.script.ModuleEnvelope;
import anvil.script.Grammar;
import anvil.script.expression.Expression;
import anvil.script.statements.taglib.TagLibrary;
import anvil.server.Address;
import anvil.server.LocalizationPreferences;
import anvil.server.Zone;
import anvil.java.util.Hashlist;
import anvil.java.util.Holder;

/**
* class ModuleStatement
*
* @author: Jani Lehtim�ki
*/
public class ModuleStatement extends DefinitionStatement
  implements Module, CodecConstants
{

  private ModuleEnvelope   _envelope;
  private Address          _address;
  private BlockStatement   _staticinit;
  private BlockStatement   _init;
  private int              _inlinecount;
  private Method           _constructor;
  private HashMap          _dependencies = new HashMap();
 

  public ModuleStatement(ModuleEnvelope envelope, Location location)
  {
    super(null, location);
    init(envelope, location);
  }


  public ModuleStatement(ModuleEnvelope envelope, Location location, String name, String document)
  {
    super(null, location, name, DocParser.parseModule(name, document));
    init(envelope, location);
    declare(new ImportedModuleStatement(name, this, _document));
  }


  private void init(ModuleEnvelope envelope, Location location)
  {
    _staticinit = new ImplicitBlockStatement(this, location);
    _init = new ImplicitBlockStatement(this, location);
    _envelope = envelope;
    _address = envelope.getAddress();
    _descriptor = envelope.getDescriptor();
    _contentstate = envelope.getAddress().getZone().getContentProcessing();
    declare(new ImportedModuleStatement("module", this, null));
    addExternal(Context.GLOBAL, Context.TYPE);
  }


  public int typeOf()
  {
    return Statement.ST_MODULE;
  }


  public String name()
  {
    return "module";
  }
 

  public int getType()
  {
    return MODULE;
  }

 
  public Scope getParent()
  {
    return null;
  }
 

  public String getQualifiedName()
  {
    return "";
  }
  

  public void addDependency(Import imprt)
  {
    Address addr = imprt.getAddress();
    if (addr != null) {
      _dependencies.put(addr, new Dependency(addr, null, imprt.getLocation()));
    }
  }
 

  public Iterator getDependencies()
  {
    return _dependencies.values().iterator();
  }


  public Dependency getDependency(Address address)
  {
    return (Dependency)_dependencies.get(address);
  }


  public ModuleEnvelope getEnvelope()
  {
    return _envelope;
  }
 

  public Address getAddress()
  {
    return _address;
  }
 

  public String getPathinfo()
  {
    return _address.getPathinfo();
  }


  public int getNextInlined()
  {
    return _inlinecount++;
  }
 
 
  public boolean isStaticRegion()
  {
    return true;
  }


  public Type lookupDeclaration(String name)
  {
    Type type = (Type)_types.get(name);
    if (type != null) {
      return type;
    }
    Namespace ns = _address.getZone().getNamespace(name);
    if (ns != null) {
      type = new ImportedNamespaceStatement(this, name, null);
      if (type != null) {
        return type;
      }
    }
    return super.lookupDeclaration(name);
  }

 
  public VariableStatement declare(Location location, String name, Expression expr, String document, boolean statik)
  {
    VariableStatement var;
    declare(var = new StaticVariableStatement(location, this, name, expr, document));
    return var;
  }


  public void parse(TemplateParser parser, Tag tag)
  {
    super.parse(parser, tag);
    String name = tag.getValue("name");
    if (name != null) {
      if (Grammar.isValidIdentifier(name)) {
        declare(new ImportedModuleStatement(name, this, null));
        _name = name;
      } else {
        parser.error(getLocation(), "Template name '"+_name+"' is invalid");
      }
    } else {
      _name = "module";
    }
    _document = DocParser.parseModule(_name, parser.getDocument());
    declare(new ImportedModuleStatement(_name, this, _document));
  }


  private void addInitializers(Enumeration types)
  {
    while(types.hasMoreElements()) {
      Type type = (Type)types.nextElement();
      switch(type.getType()) {
      case STATIC_VARIABLE:
      case CONSTANT_VARIABLE:
        VariableStatement var = (VariableStatement)type;
        _staticinit.add(new EvalStatement(_staticinit, getLocation(), var.createStaticInitializer()));
        if (!var.hasConstantInitializer()) {
          _init.add(new EvalStatement(_init, getLocation(), var.createInitializer()));
        }
        break;
      case CLASS:
      case INTERFACE:
      case NAMESPACE:
        addInitializers(((Scope)type).getDeclarations());
        break;
      }
    }

  }
 

  public void check(ErrorListener context)
  {
    super.check(context);
    addInitializers(getDeclarations());
  }

 
  public final synchronized void init(Context context)
  {
    throw new RuntimeException("Attempted to call 'void init(Context)' on ModuleStatement");
  }
 

  public void onCharacters(TemplateParser parser, String cdata)
  {
  }


  public boolean onTag(TemplateParser parser, int type, Tag tag)
  {
    switch(type) {
    case ST_TAG:
      break;

    case ST_IMPORT:
      onImport(parser, tag);
      break;

    case ST_VAR:
      onVar(parser, tag);
      break;
   
    case ST_CONST:
      onConst(parser, tag);
      break;

    case ST_FUNCTION:
      onFunction(parser, type, tag);
      break;
     
    case ST_CLASS:
      onClass(parser, type, tag);
      break;
     
    case ST_NAMESPACE:
      onNamespace(parser, type, tag);
      break;

    case ST_ENDMODULE:
      parser.pop();
      break;

    default:
      return false;
    }
   
    return true;
 
 

  public Method getConstructor()
  {
    return _constructor;
  }


  public void compileConstructor(ByteCompiler context)
  {
    ClassRoom clazz = context.getClassRoom();
    ConstantPool pool = clazz.getPool();
    Method constructor = clazz.createConstructor("()V", ACC_PUBLIC);
    _constructor = constructor;
    Code code = constructor.getCode();

    StringBuffer clsid = new StringBuffer();
    clsid.append("$Id: ");
    clsid.append(_address.getPathinfo());
    clsid.append(" 1.0 ");
    LocalizationPreferences prefs = _address.getZone().getLocalizationPreferences();
    Calendar cal = Calendar.getInstance(prefs.getTimezoneInstance(), prefs.getLocaleInstance());
    anvil.util.Conversions.toString(clsid, cal);
    Field clsidfield = clazz.createField("_id", "Ljava/lang/String;", ACC_PUBLIC|ACC_STATIC|ACC_FINAL);
    clsidfield.setConstantValue(pool.addString(clsid.toString()));

    context.pushCode(code);
    code.self();
    code.invokespecial(pool.addMethodRef("anvil/script/compiler/CompiledModule",
      "<init>", "()V"));
    context.popCode();
   
    Method versionmethod = clazz.createMethod("getVersion", "()I", ACC_PUBLIC);
    code = versionmethod.getCode();
    context.pushCode(code);
    code.iconst(_envelope.getVersion());
    code.ireturn();

    clazz.createField("_module", "Lanvil/script/compiler/CompiledModule;", ACC_PUBLIC|ACC_STATIC);
    clazz.createField("_type", "Lanvil/core/Any;", ACC_PUBLIC|ACC_STATIC);

    context.popCode();
  }
 

  public void compileStaticInit(ByteCompiler context)
  {
    ClassRoom clazz = context.getClassRoom();
    Code code = clazz.getStatic().getCode();
    ConstantPool pool = code.getPool();
    context.pushCode(code);
    if (_staticinit != null) {
      _staticinit.compile(context);
    }
    Enumeration e = _types.elements();
    while(e.hasMoreElements()) {
      Type type = (Type)e.nextElement();
      int typeid = type.getType();
      if (typeid == CLASS || typeid == INTERFACE) {
        code.getstatic(pool.addFieldRef(type.getTypeRef(pool),
          "_members", "[Ljava/lang/Object;"));
        code.pop();
      }
    }
    context.popCode();
  }
   
 
  public void compileInit(ByteCompiler context)
  {
    ClassRoom clazz = context.getClassRoom();
    Method method = clazz.createMethod("init", "(Lanvil/script/Context;)V", ACC_PUBLIC|ACC_FINAL|ACC_SYNCHRONIZED);
    Code code = method.getCode();
    context.pushCode(code);
    code.addLocal();
    if (_init != null) {
      _init.compile(context);
    }
    code.vreturn();
    context.popCode();
  }
   

  private void compileDependencies(ByteCompiler context)
  {
    ClassRoom clazz = context.getClassRoom();
    Code code = context.getCode();
    ConstantPool pool = code.getPool();
    Field field = clazz.createField("_imports", "[Ljava/lang/String;", Code.ACC_PUBLIC|Code.ACC_STATIC);
    code.iconst(_dependencies.size()*2);
    code.anewarray("java/lang/String");
    Iterator iter = _dependencies.values().iterator();
    for(int i=0; iter.hasNext(); ) {
      Dependency dep = (Dependency)iter.next();
      code.dup();
      code.iconst(i++);
      code.astring(dep.getPathinfo());
      code.aastore();
      code.dup();
      code.iconst(i++);
      code.astring(dep.getDescriptor());
      code.aastore();
    }
    code.putstatic(field);

  }


  public void compile(ByteCompiler context)
  {
    compileMembers(context, _types.size(), _types.elements());
    compileDependencies(context);
    compileConstructor(context);
    compileStaticInit(context);
    compileInit(context);
    super.compile(context);
    _constructor.getCode().vreturn();
  }

}
TOP

Related Classes of anvil.script.statements.ModuleStatement

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.