Package anvil.script

Source Code of anvil.script.ParameterListDeclaration

/*
* $Id: ParameterListDeclaration.java,v 1.22 2002/09/16 08:05:03 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;

import java.io.IOException;
import java.util.Enumeration;
import java.lang.reflect.Method;
import anvil.ErrorListener;
import anvil.core.Any;
import anvil.core.AnyTuple;
import anvil.core.Array;
import anvil.doc.Doc;
import anvil.script.expression.Expression;
import anvil.script.statements.FunctionStatement;
import anvil.script.compiler.ByteCompiler;
import anvil.codec.ClassRoom;
import anvil.codec.Code;
import anvil.codec.ConstantPool;
import anvil.codec.CodecConstants;


/**
* class ParameterListDeclaration
*
* @author: Jani Lehtim�ki
*/
public class ParameterListDeclaration implements CodecConstants
{

  public static final ParameterListDeclaration EMPTY = new ParameterListDeclaration(0).open().close();

  protected static class Parameter
  {
    protected int type;
    protected String name;
    protected Any value;
    protected Expression expression;
    protected boolean required = true;
    protected Doc doc;
  }

  private static final Integer ZERO = new Integer(0);
  private static final Long    LONG_ZERO = new Long(0);
  private static final Double  ZERO_POINT_ZERO = new Double(0.0);
  
  protected int         _size     = 0;
  protected int         _minsize  = 0;
  protected Parameter[] _params = null;

  public ParameterListDeclaration()
  {
    this(4);
  }


  public ParameterListDeclaration(int initialSize)
  {
    _params = new Parameter[initialSize];
  }


  public ParameterListDeclaration(Method method, Object[] types, Doc document)
  {
    Class params[] = method.getParameterTypes();
    int plength = params.length;
    int dptr = 0;
    int dlength = (types != null) ? types.length : 0;
    boolean hadminsize = false;
   
    _params = new Parameter[plength];
    _size = plength;
   
    if (dlength>0 && types[0] instanceof Integer) {
      _minsize = ((Integer)types[0]).intValue();
      hadminsize = true;
      dptr++;
    }
   
    if (plength>0) {   
      String[] classes = CompilableFunction.CLASSES;
     
      for(int i=0; i<plength; i++) {
        int type = -1;
        String from = params[i].getName();
        for(int c=0; c<classes.length; c++) {
          String to = classes[c];
          if (from.equals(to)) {
            type = c;
            break;
          }
        }

        if (type == -1) {
          throw new RuntimeException("Unsupported parameter type detected on '" +
            method.getName() + "' prototype: " + from);
        }

        Parameter param = new Parameter();
        param.type = type;
        if (dptr<dlength) {
          String name = (String)types[dptr++];
          if (name == null) {
            name = "$" + i;
          }
          if (name.startsWith("..")) {
            param.type = CompilableFunction.PARAMETER_REST;
            param.name = name.substring(1);
            param.required = false;
            if (dptr < dlength) {
              Object o = types[dptr++];
              if (o != null) {
                param.value = Any.create(o);
              }
            }
           
          } else if (name.startsWith("*")) {
            param.name = name.substring(1);
            param.required = false;
            if (dptr < dlength) {
              Object o = types[dptr++];
              if (o != null) {
                param.value = Any.create(o);
              }
            }
           
          } else {
            param.name = name;
          }
        } else {
          param.name = "$" + i;
        }
        _params[i] = param;
      }
    }
    if (!hadminsize) {
      close();
    }
    importDocuments(document);
  }


 
  private void expandCapacity()
  {
    int length = _params.length;
    Parameter[] params = new Parameter[length + 4];
    System.arraycopy(_params, 0, params, 0, length);
    _params = params;
  }


  public String toString()
  {
    return toString(new StringBuffer(48)).toString();
  }


  public StringBuffer toString(StringBuffer buffer)
  {
    int n = _size;
    boolean first = true;
    Parameter[] params = _params;
    for(int i=0; i<n; i++) {
      Parameter param = params[i];
      int t = param.type;
      if (t == CompilableFunction.PARAMETER_CONTEXT)  {
        continue;
      }
      if (t >= CompilableFunction.PARAMETER_ARRAY) {
        if (!first) {
          buffer.append(", ");
        } else {
          first = false;
        }
        buffer.append("..");
        buffer.append(param.name);
       
      } else {
        if (!first) {
          buffer.append(", ");
        } else {
          first = false;
        }
        if (!param.required) {
          buffer.append('*');
        }     
        buffer.append(param.name);
      }
    }
    return buffer;
  }


  public int size()
  {
    return _size;
  }
 
 
  public int minSize()
  {
    return _minsize;
  }
 
 
  public boolean isDeclared(String name)
  {
    Parameter[] params = _params;
    for(int i = _size-1; i>=0; i--) {
      if (params[i].equals(name)) {
        return true;
      }
    }
    return false;
  }


  public boolean hasDefaultValues()
  {
    Parameter[] params = _params;
    for(int i = _size-1; i>=0; i--) {
      if (!params[i].required) {
        return true;
      }
    }
    return false;
  }
 

  public String getName(int index)
  {
    if ((index >= 0) && (index < _size)) {
      return _params[index].name;
    } else {
      return "$" + index;
    }
  }


  public int getType(int index)
  {
    if ((index >= 0) && (index < _size)) {
      return _params[index].type;
    } else {
      return 0;
    }
  }
 
  public Any getDefault(int index)
  {
    if ((index >= 0) && (index < _size)) {
      return _params[index].value;
    }
    return null;
  }

  public boolean getRequired(int index)
  {
    if ((index >= 0) && (index < _size)) {
      return _params[index].required;
    } else {
      return true;
    }
  }
 
 
  public Doc getDoc(int index)
  {
    if ((index >= 0) && (index < _size)) {
      return _params[index].doc;
    } else {
      return null;
    }
  } 


  public void add(String name)
  {
    add(CompilableFunction.PARAMETER_ANY, name, null, null);
  }
 

  public void add(String name, Any value)
  {
    add(CompilableFunction.PARAMETER_ANY, name, value, null);
  }
 

  public void add(String name, Expression expr)
  {
    add(CompilableFunction.PARAMETER_ANY, name, (expr != null) ? Any.UNDEFINED : null, expr);
  }
   

  public void add(int type, String name, Any value, Expression expression)
  {
    if (_size >= _params.length) {
      expandCapacity();
    }
    Parameter param = new Parameter();
    param.type = type;
    param.name = name;
    param.value = value;
    param.expression = expression;
    param.required = (value == null);
    _params[_size++] = param;
  }


  public ParameterListDeclaration open()
  {
    add(CompilableFunction.PARAMETER_CONTEXT, "<context>", null, null);
    return this;
  }
 
 
  public ParameterListDeclaration close()
  {
    int n = _size;
    int c = 0;
    Parameter[] params = _params;
    out:
    for(int i=0; i<n; i++) {
      switch(params[i].type) {
      case CompilableFunction.PARAMETER_CONTEXT:
      case CompilableFunction.PARAMETER_ARRAY:
      case CompilableFunction.PARAMETER_ANYLIST:
      case CompilableFunction.PARAMETER_LIST:
      case CompilableFunction.PARAMETER_REST:
        break;
      default:
        {
          if (params[i].required) {
            c++;
          } else {
            break out;
          }
        }
        break;
      }
    }
    _minsize = c;
    return this;
  }
 

  public void declareTo(FunctionStatement function)
  {
    int n = _size;
    Parameter[] params = _params;
    for(int i=0; i<n; i++) {
      Parameter param = params[i];
      int type = param.type;
      if (type == CompilableFunction.PARAMETER_ANY || type == CompilableFunction.PARAMETER_REST) {
        function.declareParameter(param.name);
      }
    }
  }
 

  public void check(ErrorListener context)
  {
    Parameter[] params = _params;
    int n = _size;
    for(int i=0; i<n; i++) {
      Parameter param = params[i];
      Expression expr = param.expression;
      if (expr != null) {
        expr.check(context);
        if (expr.isConstant()) {
          param.value = expr.eval();
        } else {
          context.error(expr.getLocation(), "Default value for parameter '"+param.name+"' is not a constant");
        }
      }
    }
  }


  public void importDocuments(Doc node)
  {
    if (node != null) {
      Parameter[] params = _params;
      int length = _size;
      for(int i=0; i<length; i++) {
        Parameter param = params[i];
        if (param.type != CompilableFunction.PARAMETER_CONTEXT) {
          param.doc = node.findFirst(Doc.T_PARAM, param.name);
        }
      }
    }
  }


  public void compileDescriptor(ByteCompiler context)
  {
    ClassRoom clazz = context.getClassRoom();
    ConstantPool pool = context.getPool();
    Parameter[] params = _params;
    int size = _size;
    int count = size;
    for(int i=0; i<size; i++) {
      if (params[i].value != null) {
        count++;
      }
    }
    Code code = clazz.getStatic().getCode();
    code.iconst(count);
    code.anewarray("java/lang/Object");
    int j = 0;
    for(int i=0; i<size; i++) {
      Parameter param = params[i];
      Any defaultvalue = param.value;
      code.dup();
      code.iconst(j++);
      if (param.type == CompilableFunction.PARAMETER_REST) {
        code.astring(".."+param.name);
      } else if (defaultvalue != null) {
        code.astring("*"+param.name);
      } else {
        code.astring(param.name);
      }
      code.aastore();
      if (defaultvalue != null) { 
        code.dup();
        code.iconst(j++);
        context.constant(defaultvalue, false);
        code.aastore();
      }
    }
  } 

  
}
TOP

Related Classes of anvil.script.ParameterListDeclaration

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.