package compiler.language.parser.rules.expression;

import static compiler.language.parser.ParseType.ARRAY_ACCESS_EXPRESSION;
import static compiler.language.parser.ParseType.DIMENSION_EXPRESSION;
import static compiler.language.parser.ParseType.NESTED_QNAME_LIST;
import static compiler.language.parser.ParseType.PRIMARY_NO_TRAILING_DIMENSIONS_NOT_QNAME;
import static compiler.language.parser.ParseType.QNAME;

import compiler.language.ast.ParseInfo;
import compiler.language.ast.expression.ArrayAccessExpression;
import compiler.language.ast.expression.Expression;
import compiler.language.ast.expression.FieldAccessExpression;
import compiler.language.ast.misc.QName;
import compiler.language.ast.misc.QNameElement;
import compiler.parser.ParseException;
import compiler.parser.Rule;

/*
 * Created on 11 Aug 2010
 */

/**
 * @author Anthony Bryant
 */
public class ArrayAccessExpressionRule extends Rule
{

  private static final Object[] PRODUCTION = new Object[] {PRIMARY_NO_TRAILING_DIMENSIONS_NOT_QNAME, DIMENSION_EXPRESSION};
  private static final Object[] QNAME_PRODUCTION = new Object[] {QNAME, DIMENSION_EXPRESSION};
  private static final Object[] NESTED_QNAME_LIST_PRODUCTION = new Object[] {NESTED_QNAME_LIST, DIMENSION_EXPRESSION};

  public ArrayAccessExpressionRule()
  {
    super(ARRAY_ACCESS_EXPRESSION, PRODUCTION, QNAME_PRODUCTION, NESTED_QNAME_LIST_PRODUCTION);
  }

  /**
   * {@inheritDoc}
   * @see compiler.parser.Rule#match(java.lang.Object[], java.lang.Object[])
   */
  @Override
  public Object match(Object[] types, Object[] args) throws ParseException
  {
    if (types == PRODUCTION)
    {
      Expression expression = (Expression) args[0];
      Expression dimensionExpression = (Expression) args[1];
      return new ArrayAccessExpression(expression, dimensionExpression,
                                       ParseInfo.combine(expression.getParseInfo(), dimensionExpression.getParseInfo()));
    }
    if (types == QNAME_PRODUCTION)
    {
      QName qname = (QName) args[0];
      FieldAccessExpression fieldAccessExpression = new FieldAccessExpression(qname, qname.getParseInfo());
      Expression dimensionExpression = (Expression) args[1];
      return new ArrayAccessExpression(fieldAccessExpression, dimensionExpression,
                                       ParseInfo.combine(qname.getParseInfo(), dimensionExpression.getParseInfo()));
    }
    if (types == NESTED_QNAME_LIST_PRODUCTION)
    {
      QNameElement element = (QNameElement) args[0];
      Expression expression = element.toExpression();
      Expression dimensionExpression = (Expression) args[1];
      return new ArrayAccessExpression(expression, dimensionExpression,
                                       ParseInfo.combine(expression.getParseInfo(), dimensionExpression.getParseInfo()));
    }
    throw badTypeList();
  }

}

@@ -406,16 +406,61 @@
 QNAME;%0A%0A
+import compiler.language.ast.ParseContainer;%0A
 import c
@@ -491,16 +491,16 @@
 seInfo;%0A
-
 import c
@@ -985,32 +985,50 @@
 ct%5B%5D PRODUCTION 
+                  
 = new Object%5B%5D %7B
@@ -1133,32 +1133,44 @@
 NAME_PRODUCTION 
+            
 = new Object%5B%5D %7B
@@ -1171,24 +1171,59 @@
 ct%5B%5D %7BQNAME,
+                                   
  DIMENSION_E
@@ -1329,16 +1329,39 @@
 ME_LIST,
+                       
  DIMENSI
@@ -1803,32 +1803,84 @@
  args%5B0%5D;%0A      
+@SuppressWarnings(%22unchecked%22)%0A      ParseContainer%3C
 Expression dimen
@@ -1865,32 +1865,33 @@
 ainer%3CExpression
+%3E
  dimensionExpres
@@ -1890,32 +1890,47 @@
 onExpression = (
+ParseContainer%3C
 Expression) args
@@ -1915,32 +1915,33 @@
 ainer%3CExpression
+%3E
 ) args%5B1%5D;%0A     
@@ -1997,32 +1997,42 @@
 ensionExpression
+.getItem()
 ,%0A              
@@ -2329,32 +2329,84 @@
 eInfo());%0A      
+@SuppressWarnings(%22unchecked%22)%0A      ParseContainer%3C
 Expression dimen
@@ -2391,32 +2391,33 @@
 ainer%3CExpression
+%3E
  dimensionExpres
@@ -2416,32 +2416,47 @@
 onExpression = (
+ParseContainer%3C
 Expression) args
@@ -2441,32 +2441,33 @@
 ainer%3CExpression
+%3E
 ) args%5B1%5D;%0A     
@@ -2534,32 +2534,42 @@
 ensionExpression
+.getItem()
 ,%0A              
@@ -2835,32 +2835,84 @@
 ession();%0A      
+@SuppressWarnings(%22unchecked%22)%0A      ParseContainer%3C
 Expression dimen
@@ -2905,16 +2905,17 @@
 pression
+%3E
  dimensi
@@ -2922,32 +2922,47 @@
 onExpression = (
+ParseContainer%3C
 Expression) args
@@ -2951,24 +2951,25 @@
 r%3CExpression
+%3E
 ) args%5B1%5D;%0A 
@@ -3037,16 +3037,26 @@
 pression
+.getItem()
 ,%0A      

Fix a ClassCastExpression in ArrayAccessExpressionRule, where it assumed that DIMENSION_EXPRESSION returned the wrong type.