Пример #1
0
  @Override
  ALink analyze(Variables variables) {
    if (before == null) {
      throw new IllegalArgumentException(error("Illegal array access made without target."));
    }

    final Sort sort = before.sort;

    if (sort == Sort.ARRAY) {
      index.expected = Definition.INT_TYPE;
      index.analyze(variables);
      index = index.cast(variables);

      after = Definition.getType(before.struct, before.dimensions - 1);

      return this;
    } else if (sort == Sort.DEF) {
      return new LDefArray(line, offset, location, index).copy(this).analyze(variables);
    } else if (Map.class.isAssignableFrom(before.clazz)) {
      return new LMapShortcut(line, offset, location, index).copy(this).analyze(variables);
    } else if (List.class.isAssignableFrom(before.clazz)) {
      return new LListShortcut(line, offset, location, index).copy(this).analyze(variables);
    }

    throw new IllegalArgumentException(
        error("Illegal array access on type [" + before.name + "]."));
  }
Пример #2
0
  private void analyzeSimple(Locals locals) {
    AStoreable lhs = (AStoreable) this.lhs;

    // If the lhs node is a def optimized node we update the actual type to remove the need for a
    // cast.
    if (lhs.isDefOptimized()) {
      rhs.analyze(locals);
      rhs.expected = rhs.actual;
      lhs.updateActual(rhs.actual);
      // Otherwise, we must adapt the rhs type to the lhs type with a cast.
    } else {
      rhs.expected = lhs.actual;
      rhs.analyze(locals);
    }

    rhs = rhs.cast(locals);

    this.statement = true;
    this.actual = read ? lhs.actual : Definition.VOID_TYPE;
  }
Пример #3
0
  @Override
  void analyze(Variables variables) {
    expression.expected = Definition.OBJECT_TYPE;
    expression.internal = true;
    expression.analyze(variables);
    expression = expression.cast(variables);

    methodEscape = true;
    loopEscape = true;
    allEscape = true;

    statementCount = 1;
  }
Пример #4
0
  private void analyzeCompound(Locals locals) {
    rhs.analyze(locals);

    boolean shift = false;

    if (operation == Operation.MUL) {
      promote = AnalyzerCaster.promoteNumeric(lhs.actual, rhs.actual, true);
    } else if (operation == Operation.DIV) {
      promote = AnalyzerCaster.promoteNumeric(lhs.actual, rhs.actual, true);
    } else if (operation == Operation.REM) {
      promote = AnalyzerCaster.promoteNumeric(lhs.actual, rhs.actual, true);
    } else if (operation == Operation.ADD) {
      promote = AnalyzerCaster.promoteAdd(lhs.actual, rhs.actual);
    } else if (operation == Operation.SUB) {
      promote = AnalyzerCaster.promoteNumeric(lhs.actual, rhs.actual, true);
    } else if (operation == Operation.LSH) {
      promote = AnalyzerCaster.promoteNumeric(lhs.actual, false);
      shiftDistance = AnalyzerCaster.promoteNumeric(rhs.actual, false);
      shift = true;
    } else if (operation == Operation.RSH) {
      promote = AnalyzerCaster.promoteNumeric(lhs.actual, false);
      shiftDistance = AnalyzerCaster.promoteNumeric(rhs.actual, false);
      shift = true;
    } else if (operation == Operation.USH) {
      promote = AnalyzerCaster.promoteNumeric(lhs.actual, false);
      shiftDistance = AnalyzerCaster.promoteNumeric(rhs.actual, false);
      shift = true;
    } else if (operation == Operation.BWAND) {
      promote = AnalyzerCaster.promoteXor(lhs.actual, rhs.actual);
    } else if (operation == Operation.XOR) {
      promote = AnalyzerCaster.promoteXor(lhs.actual, rhs.actual);
    } else if (operation == Operation.BWOR) {
      promote = AnalyzerCaster.promoteXor(lhs.actual, rhs.actual);
    } else {
      throw createError(new IllegalStateException("Illegal tree structure."));
    }

    if (promote == null || (shift && shiftDistance == null)) {
      throw createError(
          new ClassCastException(
              "Cannot apply compound assignment "
                  + "["
                  + operation.symbol
                  + "=] to types ["
                  + lhs.actual
                  + "] and ["
                  + rhs.actual
                  + "]."));
    }

    cat = operation == Operation.ADD && promote.sort == Sort.STRING;

    if (cat) {
      if (rhs instanceof EBinary
          && ((EBinary) rhs).operation == Operation.ADD
          && rhs.actual.sort == Sort.STRING) {
        ((EBinary) rhs).cat = true;
      }

      rhs.expected = rhs.actual;
    } else if (shift) {
      if (promote.sort == Sort.DEF) {
        // shifts are promoted independently, but for the def type, we need object.
        rhs.expected = promote;
      } else if (shiftDistance.sort == Sort.LONG) {
        rhs.expected = Definition.INT_TYPE;
        rhs.explicit = true;
      } else {
        rhs.expected = shiftDistance;
      }
    } else {
      rhs.expected = promote;
    }

    rhs = rhs.cast(locals);

    there = AnalyzerCaster.getLegalCast(location, lhs.actual, promote, false, false);
    back = AnalyzerCaster.getLegalCast(location, promote, lhs.actual, true, false);

    this.statement = true;
    this.actual = read ? lhs.actual : Definition.VOID_TYPE;
  }