@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 + "].")); }
@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; }
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; }
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; }