public void generateOptimizedStringConcatenationCreation(
     BlockScope blockScope, CodeStream codeStream, int typeID) {
   // keep implementation in sync with BinaryExpression
   // #generateOptimizedStringConcatenationCreation
   if (this.referencesTable == null) {
     super.generateOptimizedStringConcatenationCreation(blockScope, codeStream, typeID);
   } else {
     if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS)
         && ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)
         && this.constant == Constant.NotAConstant) {
       int pc = codeStream.position;
       BinaryExpression cursor = this.referencesTable[this.arity - 1];
       // silence warnings
       int restart = 0;
       for (restart = this.arity - 1; restart >= 0; restart--) {
         if (((((cursor = this.referencesTable[restart]).bits & ASTNode.OperatorMASK)
                     >> ASTNode.OperatorSHIFT)
                 == OperatorIds.PLUS)
             && ((cursor.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) {
           if (cursor.constant != Constant.NotAConstant) {
             codeStream.newStringContatenation(); // new: java.lang.StringBuffer
             codeStream.dup();
             codeStream.ldc(cursor.constant.stringValue());
             codeStream.invokeStringConcatenationStringConstructor();
             // invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
             break;
           }
         } else {
           cursor.generateOptimizedStringConcatenationCreation(
               blockScope, codeStream, cursor.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
           break;
         }
       }
       restart++;
       if (restart == 0) { // reached the leftmost expression
         cursor.left.generateOptimizedStringConcatenationCreation(
             blockScope, codeStream, cursor.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
       }
       int pcAux;
       for (int i = restart; i < this.arity; i++) {
         codeStream.recordPositionsFrom(pc, (cursor = this.referencesTable[i]).left.sourceStart);
         pcAux = codeStream.position;
         cursor.right.generateOptimizedStringConcatenation(
             blockScope, codeStream, cursor.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
         codeStream.recordPositionsFrom(pcAux, cursor.right.sourceStart);
       }
       codeStream.recordPositionsFrom(pc, this.left.sourceStart);
       pc = codeStream.position;
       this.right.generateOptimizedStringConcatenation(
           blockScope, codeStream, this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
       codeStream.recordPositionsFrom(pc, this.right.sourceStart);
     } else {
       super.generateOptimizedStringConcatenationCreation(blockScope, codeStream, typeID);
     }
   }
 }
  /** Code generation for string literal */
  public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {

    int pc = codeStream.position;
    if (valueRequired) codeStream.ldc(constant.stringValue());
    codeStream.recordPositionsFrom(pc, this.sourceStart);
  }
  public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
    if (!valueRequired) currentScope.problemReporter().unusedObjectAllocation(this);
    int pc = codeStream.position;
    MethodBinding codegenBinding = this.binding.original();
    ReferenceBinding allocatedType = codegenBinding.declaringClass;
    codeStream.new_(allocatedType);
    boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
    if (valueRequired || isUnboxing) {
      codeStream.dup();
    }
    // better highlight for allocation: display the type individually
    if (this.type != null) { // null for enum constant body
      codeStream.recordPositionsFrom(pc, this.type.sourceStart);
    } else {
      // push enum constant name and ordinal
      codeStream.ldc(String.valueOf(this.enumConstant.name));
      codeStream.generateInlinedValue(this.enumConstant.binding.id);
    }
    // handling innerclass instance allocation - enclosing instance arguments
    if (allocatedType.isNestedType()) {
      codeStream.generateSyntheticEnclosingInstanceValues(
          currentScope, allocatedType, enclosingInstance(), this);
    }
    // generate the arguments for constructor
    generateArguments(this.binding, this.arguments, currentScope, codeStream);
    // handling innerclass instance allocation - outer local arguments
    if (allocatedType.isNestedType()) {
      codeStream.generateSyntheticOuterArgumentValues(currentScope, allocatedType, this);
    }

    // invoke constructor
    if (this.syntheticAccessor == null) {
      codeStream.invoke(
          Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */);
    } else {
      // synthetic accessor got some extra arguments appended to its signature, which need values
      for (int i = 0,
              max = this.syntheticAccessor.parameters.length - codegenBinding.parameters.length;
          i < max;
          i++) {
        codeStream.aconst_null();
      }
      codeStream.invoke(
          Opcodes.OPC_invokespecial, this.syntheticAccessor, null /* default declaringClass */);
    }
    if (valueRequired) {
      codeStream.generateImplicitConversion(this.implicitConversion);
    } else if (isUnboxing) {
      // conversion only generated if unboxing
      codeStream.generateImplicitConversion(this.implicitConversion);
      switch (postConversionType(currentScope).id) {
        case T_long:
        case T_double:
          codeStream.pop2();
          break;
        default:
          codeStream.pop();
      }
    }
    codeStream.recordPositionsFrom(pc, this.sourceStart);

    if (this.anonymousType != null) {
      this.anonymousType.generateCode(currentScope, codeStream);
    }
  }