protected override Void handleYield(YieldStatementNode yieldStatement, Void source) { var returnType = context.CodeValidationContext.CurrentMethod.ReturnType; var value = yieldStatement.Value; if (returnType == null) { if (value != null) { this.ExpressionValidator.handleExpression(value, returnType, true); } } else { var elementType = BytecodeHelper.getIterableOrIteratorElementType(returnType); if (elementType == null) { throw context.error(CompileErrorId.YieldOutsideIterator, yieldStatement); } if (value != null) { this.ExpressionValidator.handleExpression(value, elementType, true); ValidationHelper.setBoxing(context, elementType, value); if (!ValidationHelper.isAssignable(context, elementType, value)) { throw context.error(CompileErrorId.NoImplicitConversion, value, BytecodeHelper.getDisplayName(ValidationHelper.getType(context, value)), BytecodeHelper.getDisplayName(elementType)); } } } if (context.Iterables[context.CodeValidationContext.CurrentMethod] == null) { var prefix = "_" + context.CodeValidationContext.CurrentMethod.Name + "_Iterable"; int n = context.CurrentType.NestedTypes.count(p => p.Name.startsWith(prefix)); var typeBuilder = ((TypeBuilder)context.CurrentType).defineNestedType(prefix + n); typeBuilder.setSourceFile(PathHelper.getFileName(yieldStatement.Filename)); typeBuilder.setSynthetic(true); typeBuilder.setSuper(true); context.Iterables[context.CodeValidationContext.CurrentMethod] = typeBuilder; context.TypeBuilders.add(typeBuilder); typeBuilder.setBaseType(context.TypeSystem.ObjectType); } return(null); }
protected override Void handleForeach(ForeachStatementNode foreachStatement, Void src) { try { context.MemberResolver.enterScope(); var source = foreachStatement.Source; this.ExpressionValidator.handleExpression(source, null, true); var sinfo = source.getUserData(typeof(ExpressionInfo)); if (sinfo == null) { throw context.error(CompileErrorId.NoImplicitConversion, source, "<null>", BytecodeHelper.getDisplayName(context.TypeSystem.getType("java/lang/Iterable"))); } var sourceType = ValidationHelper.getType(context, source); TypeInfo elementType; if (sourceType.IsArray) { elementType = sourceType.ElementType; } else { var iterableType = BytecodeHelper.getImplementedIterable(sourceType); if (iterableType == null) { throw context.error(CompileErrorId.NoImplicitConversion, source, BytecodeHelper.getDisplayName(sourceType), BytecodeHelper.getDisplayName(context.TypeSystem.getType("java/lang/Iterable"))); } foreachStatement.addOrReplaceUserData(iterableType); elementType = BytecodeHelper.getIterableOrIteratorElementType(iterableType); } var localName = context.getIdentifier(foreachStatement.NameOffset, foreachStatement.NameLength); if (context.MemberResolver.hasLocal(localName)) { context.addError(CompileErrorId.VariableRedefinition, foreachStatement, localName); } var local = context.MemberResolver.defineLocal(localName, ValidationHelper.getVariableType(context, elementType), context.CodeValidationContext.CurrentMethod); foreachStatement.addOrReplaceUserData(local); handleStatement(foreachStatement.Statement, null); } finally { context.MemberResolver.leaveScope(); } return(null); }