private void setNestedInterfaceModifiers(InterfaceDeclarationNode interfaceDeclaration, TypeBuilder typeBuilder) {
     foreach (var modifier in interfaceDeclaration.Modifiers) {
         switch (modifier) {
         case Public:
             if (typeBuilder.IsNestedPrivate || typeBuilder.IsNestedProtected) {
                 context.addError(CompileErrorId.PublicProtectedPrivate, interfaceDeclaration);
             } else {
                 typeBuilder.setPublic(true);
                 typeBuilder.setNestedPublic(true);
             }
             break;
             
         case Protected:
             if (typeBuilder.IsNestedPrivate || typeBuilder.IsNestedPublic) {
                 context.addError(CompileErrorId.PublicProtectedPrivate, interfaceDeclaration);
             } else {
                 typeBuilder.setNestedProtected(true);
             }
             break;
             
         case Private:
             if (typeBuilder.IsNestedProtected || typeBuilder.IsNestedPublic) {
                 context.addError(CompileErrorId.PublicProtectedPrivate, interfaceDeclaration);
             } else {
                 typeBuilder.setNestedPrivate(true);
             }
             break;
             
         case Abstract:
             break;
             
         default:
             context.addError(CompileErrorId.UnexpectedModifier, interfaceDeclaration, modifier.toString().toLowerCase());
             break;
         }
     }
 }
 private void setInterfaceBaseTypes(InterfaceDeclarationNode interfaceDeclaration) {
     var typeBuilder = interfaceDeclaration.getUserData(typeof(TypeBuilder));
     context.MemberResolver.enterType(typeBuilder);
     try {
         typeBuilder.setBaseType(context.TypeSystem.ObjectType);
         foreach (var typeReference in interfaceDeclaration.InterfaceBase) {
             var type = CompilerHelper.resolveTypeReference(context, typeBuilder.PackageName, typeReference);
             if (!type.IsInterface) {
                 context.addError(CompileErrorId.ClassInInterfaceList, typeReference,
                     BytecodeHelper.getDisplayName(typeBuilder), BytecodeHelper.getDisplayName(type));
                     continue;
             }
             typeBuilder.addInterface(type);
             if (type.FullName.equals("java/lang/annotation/Annotation")) {
                 typeBuilder.setAnnotation(true);
             }
         }
     } finally {
         context.MemberResolver.leaveType();
     }
 }
 private void defineNestedInterface(TypeBuilder declaringClass, InterfaceDeclarationNode interfaceDeclaration) {
     var shortName = context.getIdentifier(interfaceDeclaration.NameOffset, interfaceDeclaration.NameLength);
     var className = declaringClass.FullName + '$' + shortName;
     TypeBuilder typeBuilder = null;
     if (interfaceDeclaration.IsPartial) {
         var partialTypeInfo = this.partialTypes[className];
         if (partialTypeInfo != null) {
             setNestedInterfaceModifiers(interfaceDeclaration, partialTypeInfo.typeBuilder);
             typeBuilder = partialTypeInfo.typeBuilder;
         }
     }
     if (typeBuilder == null) {
         typeBuilder = defineNestedType(declaringClass, className, shortName, interfaceDeclaration);
         setNestedInterfaceModifiers(interfaceDeclaration, typeBuilder);
         if (interfaceDeclaration.IsPartial) {
             this.partialTypes[className] = new PartialTypeInfo(typeBuilder);
         }
     }
     setTypeParameters(typeBuilder, interfaceDeclaration.TypeParameters, interfaceDeclaration);
     interfaceDeclaration.addUserData(typeBuilder);
     typeBuilder.setInterface(true);
     typeBuilder.setAbstract(true);
 }
 private void setInterfaceModifiers(InterfaceDeclarationNode interfaceDeclaration, TypeBuilder typeBuilder) {
     foreach (var modifier in interfaceDeclaration.Modifiers) {
         switch (modifier) {
         case Public:
             typeBuilder.setPublic(true);
             break;
             
         case Abstract:
             break;
             
         default:
             context.addError(CompileErrorId.UnexpectedModifier, interfaceDeclaration, modifier.toString().toLowerCase());
             break;
         }
     }
 }
 private void defineInterface(String packageName, InterfaceDeclarationNode interfaceDeclaration) {
     var className = getTypeName(packageName, interfaceDeclaration.NameOffset, interfaceDeclaration.NameLength);
     TypeBuilder typeBuilder = null;
     if (interfaceDeclaration.IsPartial) {
         var partialTypeInfo = this.partialTypes[className];
         if (partialTypeInfo != null) {
             setInterfaceModifiers(interfaceDeclaration, partialTypeInfo.typeBuilder);
             typeBuilder = partialTypeInfo.typeBuilder;
         }
     }
     if (typeBuilder == null) {
         typeBuilder = defineType(className, interfaceDeclaration);
         setInterfaceModifiers(interfaceDeclaration, typeBuilder);
         if (interfaceDeclaration.IsPartial) {
             this.partialTypes[className] = new PartialTypeInfo(typeBuilder);
         }
     }
     setTypeParameters(typeBuilder, interfaceDeclaration.TypeParameters, interfaceDeclaration);
     interfaceDeclaration.addUserData(typeBuilder);
     typeBuilder.setInterface(true);
     typeBuilder.setAbstract(true);
 }
 private void defineInterfaceMembers(InterfaceDeclarationNode interfaceDeclaration) {
     var typeBuilder = interfaceDeclaration.getUserData(typeof(TypeBuilder));
     context.CurrentType = typeBuilder;
     context.MemberResolver.enterType(typeBuilder);
     try {
         setTypeConstraints(interfaceDeclaration.ConstraintsClauses, typeBuilder);
         
         foreach (var member in interfaceDeclaration.Members) {
             switch (member.TypeMemberKind) {
             case Method:
                 defineInterfaceMethod((MethodDeclarationNode)member, typeBuilder);
                 break;
             case Indexer:
                 defineInterfaceIndexer((IndexerDeclarationNode)member, typeBuilder);
                 break;
             case Property:
                 defineInterfaceProperty((PropertyDeclarationNode)member, typeBuilder);
                 break;
             case EnumConstant:
             case Class:
             case Interface:
             case Delegate:
             case Constructor:
             case Destructor:
             case Field:
             default:
                 throw new Exception("Internal error: unhandled member kind: " + member.TypeMemberKind);
             }
             context.CurrentType = typeBuilder;
         }
     } finally {
         context.MemberResolver.leaveType();
     }
 }
		public void enterInterface(InterfaceDeclarationNode declaration) {
			typeInfos.add(declaration.getUserData(typeof(TypeInfo)));
		}
        private InterfaceDeclarationNode parseInterface(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers,
                bool partial, int startPosition) {
            if (!isIdentifier(lexicalUnit)) {
                throw error(ParseErrorId.IdentifierExpected);
            }
            var declaration = new InterfaceDeclarationNode { IsPartial = partial,
                NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength(), StartPosition = startPosition };
            if (docCommentEndPosition > 0) {
                declaration.DocumentationOffset = docCommentStartPosition;
                declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition;
                docCommentEndPosition = 0;
            }
            setScannerState(declaration);
            declaration.Modifiers.addAll(modifiers);
            declaration.Annotations.addAll(annotations);
            nextLexicalUnit(true);
            parseTypeParameters(declaration.TypeParameters);
            parseClassBase(declaration.InterfaceBase);
            parseTypeParameterConstraintsClauses(declaration.ConstraintsClauses);
            if (lexicalUnit != LexicalUnit.OpenBrace) {
                throw error(ParseErrorId.OpenBraceExpected);
            }
            if (nextLexicalUnit(true) != LexicalUnit.CloseBrace) {
                var done = false;
                annotations.clear();
                do {
                    while (lexicalUnit == LexicalUnit.OpenBracket) {
                        annotations.add(parseAnnotationSection());
                    }
                    switch (lexicalUnit) {
                    case CloseBrace:
                        if (annotations.size() > 0) {
                            addError(ParseErrorId.TypeExpected);
                            annotations.clear();
                        }
                        done = true;
                        break;

                    case Keyword:
                    case ContextualKeyword:
                    case Identifier:
                        declaration.Members.add(parseInterfaceMember(annotations, modifiers, startPosition));
                        modifiers.clear();
                        annotations.clear();
                        break;

                    default:
                        throw error(ParseErrorId.CloseBraceExpected);
                    }
                } while (!done);
            }
            if (lexicalUnit != LexicalUnit.CloseBrace) {
                throw error(ParseErrorId.CloseBraceExpected);
            }
            docCommentEndPosition = 0;
			declaration.EndPosition = scanner.EndPosition;
            if (nextLexicalUnit(false) == LexicalUnit.SemiColon) {
				declaration.EndPosition = scanner.EndPosition;
                nextLexicalUnit(false);
            }
            return declaration;
        }
		private void print(InterfaceDeclarationNode interfaceDeclaration, int indent, StringBuilder sb) {
			var indentText = buildIndentText(indent);
			foreach (var attr in interfaceDeclaration.Annotations) {
				sb.append(indentText);
				print(attr, true, sb);
			}
			sb.append(indentText);
			print(interfaceDeclaration.Modifiers, sb);
			sb.append("interface ");
			sb.append(new String(text, interfaceDeclaration.NameOffset, interfaceDeclaration.NameLength));
			if (interfaceDeclaration.TypeParameters.size() > 0) {
				sb.append("<");
				var first = true;
				foreach (var t in interfaceDeclaration.TypeParameters) {
					if (first) {
						first = false;
					} else {
						sb.append(", ");
					}
					print(t, sb);
				}
				sb.append(">");
			}
			if (interfaceDeclaration.InterfaceBase.size() > 0) {
				sb.append(" : ");
				bool first = true;
				foreach (var t in interfaceDeclaration.InterfaceBase) {
					if (first) {
						first = false;
					} else {
						sb.append(", ");
					}
					print(t, sb);
				}
			}
			print(interfaceDeclaration.ConstraintsClauses, indentText, sb);
			sb.append(" {\r\n");
			foreach (var m in interfaceDeclaration.Members) {
				switch (m.TypeMemberKind) {
				case Method:
					var methodDeclaration = (MethodDeclarationNode)m;
					foreach (var attr in methodDeclaration.Annotations) {
						sb.append(buildIndentText(indent + 1));
						print(attr, true, sb);
					}
					sb.append(buildIndentText(indent + 1));
					print(methodDeclaration.Modifiers, sb);
					print(methodDeclaration.ReturnType, sb);
					sb.append(" ");
					sb.append(new String(text, methodDeclaration.NameOffset, methodDeclaration.NameLength));
					var first = true;
					if (methodDeclaration.TypeParameters.size() > 0) {
						sb.append("<");
						first = true;
						foreach (var t in methodDeclaration.TypeParameters) {
							if (first) {
								first = false;
							} else {
								sb.append(", ");
							}
							print(t, sb);
						}
						sb.append(">");
					}
					sb.append("(");
					first = true;
					foreach (var p in methodDeclaration.Parameters) {
						if (first) {
							first = false;
						} else {
							sb.append(", ");
						}
						print(p, sb);
					}
					sb.append(")");
					print(methodDeclaration.ConstraintsClauses, buildIndentText(indent + 1), sb);
					if (methodDeclaration.Body != null) {
						sb.append(" ");
						print(methodDeclaration.Body, indent + 1, sb);
					} else {
						sb.append(";\r\n");
					}
					break;

				case Property:
					var propertyDeclaration = (PropertyDeclarationNode)m;
					foreach (var attr in propertyDeclaration.Annotations) {
						sb.append(buildIndentText(indent + 1));
						print(attr, true, sb);
					}
					sb.append(buildIndentText(indent + 1));
					print(propertyDeclaration.Modifiers, sb);
					print(propertyDeclaration.Type, sb);
					sb.append(" ");
					sb.append(new String(text, propertyDeclaration.NameOffset, propertyDeclaration.NameLength));
					sb.append(" {\r\n");
					if (propertyDeclaration.GetAccessor != null) {
						print(propertyDeclaration.GetAccessor, true, indent + 1, sb);
					}
					if (propertyDeclaration.SetAccessor != null) {
						print(propertyDeclaration.SetAccessor, false, indent + 1, sb);
					}
					sb.append(buildIndentText(indent + 1));
					sb.append("}\r\n");
					break;

				case Indexer:
					var indexerDeclaration = (IndexerDeclarationNode)m;
					foreach (var attr in indexerDeclaration.Annotations) {
						sb.append(buildIndentText(indent + 1));
						print(attr, true, sb);
					}
					sb.append(buildIndentText(indent + 1));
					print(indexerDeclaration.Modifiers, sb);
					print(indexerDeclaration.Type, sb);
					sb.append(" ");
					sb.append("this[");
					first = true;
					foreach (var p in indexerDeclaration.Parameters) {
						if (first) {
							first = false;
						} else {
							sb.append(", ");
						}
						print(p, sb);
					}
					sb.append("] {\r\n");
					if (indexerDeclaration.GetAccessor != null) {
						print(indexerDeclaration.GetAccessor, true, indent + 1, sb);
					}
					if (indexerDeclaration.SetAccessor != null) {
						print(indexerDeclaration.SetAccessor, false, indent + 1, sb);
					}
					sb.append(buildIndentText(indent + 1));
					sb.append("}\r\n");
					break;
				}
			}
			sb.append(indentText);
			sb.append("}\r\n");
		}