private void setNestedClassModifiers(ClassDeclarationNode classDeclaration, TypeBuilder typeBuilder) { foreach (var modifier in classDeclaration.Modifiers) { switch (modifier) { case Public: if (typeBuilder.IsNestedPrivate || typeBuilder.IsNestedProtected) { context.addError(CompileErrorId.PublicProtectedPrivate, classDeclaration); } else { typeBuilder.setPublic(true); typeBuilder.setNestedPublic(true); } break; case Protected: if (typeBuilder.IsNestedPrivate || typeBuilder.IsNestedPublic) { context.addError(CompileErrorId.PublicProtectedPrivate, classDeclaration); } else { typeBuilder.setNestedProtected(true); } break; case Private: if (typeBuilder.IsNestedProtected || typeBuilder.IsNestedPublic) { context.addError(CompileErrorId.PublicProtectedPrivate, classDeclaration); } else { typeBuilder.setNestedPrivate(true); } break; case Final: case Static: if (typeBuilder.IsAbstract || typeBuilder.IsFinal) { context.addError(CompileErrorId.FinalAbstractStaticClass, classDeclaration); } else { typeBuilder.setFinal(true); typeBuilder.setNestedFinal(true); } break; case Abstract: if (typeBuilder.IsFinal) { context.addError(CompileErrorId.FinalAbstractStaticClass, classDeclaration); } else { typeBuilder.setAbstract(true); typeBuilder.setNestedAbstract(true); } break; default: context.addError(CompileErrorId.UnexpectedModifier, classDeclaration, modifier.toString().toLowerCase()); break; } } }
private void setClassBaseTypes(ClassDeclarationNode classDeclaration) { var typeBuilder = classDeclaration.getUserData(typeof(TypeBuilder)); context.MemberResolver.enterType(typeBuilder); try { var first = true; foreach (var typeReference in classDeclaration.ClassBase) { var type = CompilerHelper.resolveTypeReference(context, typeBuilder.PackageName, typeReference); if (first) { first = false; if (type.IsInterface) { typeBuilder.addInterface(type); } else { if (type.IsGenericParameter) { context.addError(CompileErrorId.DeriveFromTypeVariable, typeReference, BytecodeHelper.getDisplayName(type)); continue; } if (typeBuilder.BaseType != null && typeBuilder.BaseType != type) { context.addError(CompileErrorId.DifferentPartialBaseClass, typeReference, BytecodeHelper.getDisplayName(typeBuilder)); continue; } if (type.IsFinal) { context.addError(CompileErrorId.FinalBaseClass, typeReference, BytecodeHelper.getDisplayName(typeBuilder), BytecodeHelper.getDisplayName(type)); continue; } if ((typeBuilder.IsPublic && !type.IsPublic) || (!typeBuilder.IsNestedPrivate && type.IsNestedPrivate)) { context.addError(CompileErrorId.InconsistentBaseTypeAccessibility, typeReference, BytecodeHelper.getDisplayName(typeBuilder), BytecodeHelper.getDisplayName(type)); } typeBuilder.setBaseType(type); } } else { if (!type.IsInterface) { if (typeBuilder.BaseType != null) { context.addError(CompileErrorId.MultipleBaseClass, typeReference, BytecodeHelper.getDisplayName(typeBuilder), BytecodeHelper.getDisplayName(type), BytecodeHelper.getDisplayName(typeBuilder.BaseType)); } else { context.addError(CompileErrorId.BaseClassBeforeInterfaces, typeReference, BytecodeHelper.getDisplayName(type)); } } typeBuilder.addInterface(type); } } if (typeBuilder.BaseType == null) { if (classDeclaration.IsEnum) { typeBuilder.setEnum(true); var enumType = context.TypeSystem.getType("java/lang/Enum"); typeBuilder.setBaseType(context.TypeSystem.getGenericType(enumType, Collections.singletonList<TypeInfo>(typeBuilder))); } else { typeBuilder.setBaseType(context.TypeSystem.ObjectType); } } foreach (var member in classDeclaration.Members) { switch (member.TypeMemberKind) { case Class: setClassBaseTypes((ClassDeclarationNode)member); break; case Interface: setInterfaceBaseTypes((InterfaceDeclarationNode)member); break; case Delegate: setDelegateBaseTypes((DelegateDeclarationNode)member); break; case Constructor: case Destructor: case EnumConstant: case Field: case Indexer: case Method: case Property: break; default: throw new Exception("Internal error: unhandled member kind: " + member.TypeMemberKind); } } } finally { context.MemberResolver.leaveType(); } }
private void defineNestedClass(TypeBuilder declaringClass, ClassDeclarationNode classDeclaration) { var shortName = context.getIdentifier(classDeclaration.NameOffset, classDeclaration.NameLength); var className = declaringClass.FullName + '$' + shortName; TypeBuilder typeBuilder = null; if (classDeclaration.IsPartial) { var partialTypeInfo = this.partialTypes[className]; if (partialTypeInfo != null) { setNestedClassModifiers(classDeclaration, partialTypeInfo.typeBuilder); typeBuilder = partialTypeInfo.typeBuilder; } } if (typeBuilder == null) { typeBuilder = defineNestedType(declaringClass, className, shortName, classDeclaration); setNestedClassModifiers(classDeclaration, typeBuilder); if (classDeclaration.IsPartial) { this.partialTypes[className] = new PartialTypeInfo(typeBuilder); } } setTypeParameters(typeBuilder, classDeclaration.TypeParameters, classDeclaration); classDeclaration.addUserData(typeBuilder); typeBuilder.addUserData(classDeclaration); typeBuilder.setSuper(true); typeBuilder.setNestedStatic(true); defineNestedTypes(typeBuilder, classDeclaration); }
private void defineNestedTypes(TypeBuilder declaringClass, ClassDeclarationNode classDeclaration) { foreach (var member in classDeclaration.Members) { switch (member.TypeMemberKind) { case Class: defineNestedClass(declaringClass, (ClassDeclarationNode)member); break; case Interface: defineNestedInterface(declaringClass, (InterfaceDeclarationNode)member); break; case Delegate: defineNestedDelegate(declaringClass, (DelegateDeclarationNode)member); break; case Constructor: case Destructor: case EnumConstant: case Field: case Indexer: case Method: case Property: break; default: throw new Exception("Internal error: unhandled member kind: " + member.TypeMemberKind); } } }
private void defineClass(String packageName, ClassDeclarationNode classDeclaration) { var className = getTypeName(packageName, classDeclaration.NameOffset, classDeclaration.NameLength); TypeBuilder typeBuilder = null; if (classDeclaration.IsPartial) { var partialTypeInfo = this.partialTypes[className]; if (partialTypeInfo != null) { setClassModifiers(classDeclaration, partialTypeInfo.typeBuilder); typeBuilder = partialTypeInfo.typeBuilder; } } if (typeBuilder == null) { typeBuilder = defineType(className, classDeclaration); setClassModifiers(classDeclaration, typeBuilder); if (classDeclaration.IsPartial) { this.partialTypes[className] = new PartialTypeInfo(typeBuilder); } } setTypeParameters(typeBuilder, classDeclaration.TypeParameters, classDeclaration); classDeclaration.addUserData(typeBuilder); typeBuilder.addUserData(classDeclaration); typeBuilder.setSuper(true); defineNestedTypes(typeBuilder, classDeclaration); }
private void defineClassMembers(ClassDeclarationNode classDeclaration) { var typeBuilder = classDeclaration.getUserData(typeof(TypeBuilder)); context.CurrentType = typeBuilder; context.MemberResolver.enterType(typeBuilder); try { setTypeConstraints(classDeclaration.ConstraintsClauses, typeBuilder); if (typeBuilder.IsEnum) { var fieldBuilder = typeBuilder.defineField("ENUM$VALUES", typeBuilder.ArrayType); fieldBuilder.setPrivate(true); fieldBuilder.setFinal(true); fieldBuilder.setStatic(true); var methodBuilder = typeBuilder.defineMethod("valueOf"); methodBuilder.setPublic(true); methodBuilder.setStatic(true); methodBuilder.setReturnType(typeBuilder); var param = methodBuilder.addParameter(context.TypeSystem.StringType); param.setName("str"); methodBuilder = typeBuilder.defineMethod("values"); methodBuilder.setPublic(true); methodBuilder.setStatic(true); methodBuilder.setReturnType(typeBuilder.ArrayType); } foreach (var member in classDeclaration.Members) { switch (member.TypeMemberKind) { case Class: defineClassMembers((ClassDeclarationNode)member); break; case Interface: defineInterfaceMembers((InterfaceDeclarationNode)member); break; case Delegate: defineDelegateMembers((DelegateDeclarationNode)member); break; case Method: defineClassMethod((MethodDeclarationNode)member, classDeclaration.IsPartial, typeBuilder); break; case Field: defineClassField((FieldDeclarationNode)member, typeBuilder); break; case EnumConstant: defineEnumConstant((EnumConstantDeclarationNode)member, typeBuilder); break; case Indexer: defineClassIndexer((IndexerDeclarationNode)member, typeBuilder); break; case Property: defineClassProperty((PropertyDeclarationNode)member, typeBuilder); break; case Constructor: defineClassConstructor((ConstructorDeclarationNode)member, typeBuilder); break; case Destructor: defineClassDestructor((DestructorDeclarationNode)member, typeBuilder); break; default: throw new Exception("Internal error: unhandled member kind: " + member.TypeMemberKind); } context.CurrentType = typeBuilder; } } finally { context.MemberResolver.leaveType(); } }
public void enterClass(ClassDeclarationNode declaration) { typeInfos.add(declaration.getUserData(typeof(TypeInfo))); }
private ClassDeclarationNode parseClass(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, bool isEnum, bool partial, int startPosition) { if (!isIdentifier(lexicalUnit)) { throw error(ParseErrorId.IdentifierExpected); } var result = new ClassDeclarationNode { IsEnum = isEnum, IsPartial = partial, NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength(), StartPosition = startPosition }; if (docCommentEndPosition > 0) { result.DocumentationOffset = docCommentStartPosition; result.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setScannerState(result); result.Modifiers.addAll(modifiers); result.Annotations.addAll(annotations); nextLexicalUnit(true); if (!isEnum) { parseTypeParameters(result.TypeParameters); } parseClassBase(result.ClassBase); if (!isEnum) { parseTypeParameterConstraintsClauses(result.ConstraintsClauses); } if (lexicalUnit != LexicalUnit.OpenBrace) { throw error(ParseErrorId.OpenBraceExpected); } result.EndPosition = parseClassBody(annotations, modifiers, isEnum, result.Members); if (lexicalUnit == LexicalUnit.SemiColon) { nextLexicalUnit(false); } return result; }
private void print(ClassDeclarationNode classDeclaration, int indent, StringBuilder sb) { var indentText = buildIndentText(indent); foreach (var attr in classDeclaration.Annotations) { print(attr, true, sb); } sb.append(indentText); print(classDeclaration.Modifiers, sb); if (classDeclaration.IsEnum) { sb.append("enum "); } else { sb.append("class "); } sb.append(new String(text, classDeclaration.NameOffset, classDeclaration.NameLength)); print(classDeclaration.TypeParameters, sb); if (classDeclaration.ClassBase.size() > 0) { sb.append(" : "); bool first = true; foreach (var t in classDeclaration.ClassBase) { if (first) { first = false; } else { sb.append(", "); } print(t, sb); } } print(classDeclaration.ConstraintsClauses, indentText, sb); sb.append(" {\r\n"); print(classDeclaration.Members, indent, sb); sb.append(indentText); sb.append("}\r\n"); }