Example #1
0
        MemberList GetMemberList()
        {
            var result = LazyInit.VolatileRead(ref this.memberList);

            if (result != null)
            {
                return(result);
            }
            List <IUnresolvedMember>   unresolvedMembers  = new List <IUnresolvedMember>();
            List <ITypeResolveContext> contextPerMember   = new List <ITypeResolveContext>();
            List <PartialMethodInfo>   partialMethodInfos = null;
            bool addDefaultConstructorIfRequired          = false;

            foreach (IUnresolvedTypeDefinition part in parts)
            {
                ITypeResolveContext parentContextForPart = part.CreateResolveContext(parentContext);
                ITypeResolveContext contextForPart       = parentContextForPart.WithCurrentTypeDefinition(this);
                foreach (var member in part.Members)
                {
                    if (member is IUnresolvedMethod method && method.IsPartial)
                    {
                        // Merge partial method declaration and implementation
                        if (partialMethodInfos == null)
                        {
                            partialMethodInfos = new List <PartialMethodInfo>();
                        }
                        PartialMethodInfo newInfo      = new PartialMethodInfo(method, contextForPart);
                        PartialMethodInfo existingInfo = null;
                        foreach (var info in partialMethodInfos)
                        {
                            if (newInfo.IsSameSignature(info, Compilation.NameComparer))
                            {
                                existingInfo = info;
                                break;
                            }
                        }
                        if (existingInfo != null)
                        {
                            // Add the unresolved method to the PartialMethodInfo:
                            existingInfo.AddPart(method, contextForPart);
                        }
                        else
                        {
                            partialMethodInfos.Add(newInfo);
                        }
                    }
Example #2
0
        MemberList GetMemberList()
        {
            var result = LazyInit.VolatileRead(ref this.memberList);

            if (result != null)
            {
                return(result);
            }
            List <IUnresolvedMember>   unresolvedMembers  = new List <IUnresolvedMember>();
            List <ITypeResolveContext> contextPerMember   = new List <ITypeResolveContext>();
            List <PartialMethodInfo>   partialMethodInfos = null;
            bool addDefaultConstructorIfRequired          = false;

            foreach (IUnresolvedTypeDefinition part in parts)
            {
                ITypeResolveContext parentContextForPart = part.CreateResolveContext(parentContext);
                ITypeResolveContext contextForPart       = parentContextForPart.WithCurrentTypeDefinition(this);
                foreach (var member in part.Members)
                {
                    IUnresolvedMethod method = member as IUnresolvedMethod;
                    if (method != null && method.IsPartial)
                    {
                        // Merge partial method declaration and implementation
                        if (partialMethodInfos == null)
                        {
                            partialMethodInfos = new List <PartialMethodInfo>();
                        }
                        PartialMethodInfo newInfo      = new PartialMethodInfo(method, contextForPart);
                        PartialMethodInfo existingInfo = null;
                        foreach (var info in partialMethodInfos)
                        {
                            if (newInfo.IsSameSignature(info, Compilation.NameComparer))
                            {
                                existingInfo = info;
                                break;
                            }
                        }
                        if (existingInfo != null)
                        {
                            // Add the unresolved method to the PartialMethodInfo:
                            existingInfo.AddPart(method, contextForPart);
                        }
                        else
                        {
                            partialMethodInfos.Add(newInfo);
                        }
                    }
                    else
                    {
                        unresolvedMembers.Add(member);
                        contextPerMember.Add(contextForPart);
                    }
                }

                addDefaultConstructorIfRequired |= part.AddDefaultConstructorIfRequired;
            }
            if (addDefaultConstructorIfRequired)
            {
                TypeKind kind = this.Kind;
                if (kind == TypeKind.Class && !this.IsStatic && !unresolvedMembers.Any(m => m.SymbolKind == SymbolKind.Constructor && !m.IsStatic) ||
                    kind == TypeKind.Enum || kind == TypeKind.Struct)
                {
                    contextPerMember.Add(parts[0].CreateResolveContext(parentContext).WithCurrentTypeDefinition(this));
                    unresolvedMembers.Add(DefaultUnresolvedMethod.CreateDefaultConstructor(parts[0]));
                }
            }
            result = new MemberList(contextPerMember, unresolvedMembers, partialMethodInfos);
            return(LazyInit.GetOrSet(ref this.memberList, result));
        }
Example #3
0
 public bool IsSameSignature(PartialMethodInfo other, StringComparer nameComparer)
 {
     return(nameComparer.Equals(this.Name, other.Name) &&
            this.TypeParameterCount == other.TypeParameterCount &&
            ParameterListComparer.Instance.Equals(this.Parameters, other.Parameters));
 }
 private void defineClassMethod(MethodDeclarationNode methodDeclaration, bool partial, TypeBuilder typeBuilder) {
     var name = context.getIdentifier(methodDeclaration.NameOffset, methodDeclaration.NameLength);
     if (name.equals("finalize") && methodDeclaration.Parameters.size() == 0) {
         context.addError(CompileErrorId.FinalizeMethodOverride, methodDeclaration);
     }
     if (methodDeclaration.IsPartial) {
         if (!partial) {
             context.addError(CompileErrorId.PartialMethodWithinPartialClass, methodDeclaration);
         }
         if (methodDeclaration.ReturnType != context.TypeSystem.VoidType) {
             context.addError(CompileErrorId.PartialMethodNotVoid, methodDeclaration);
         }
     }
     var methodBuilder = lookupMethod(typeBuilder, methodDeclaration.TypeParameters, methodDeclaration.Parameters, name);
     if (methodBuilder != null) {
         if (!methodDeclaration.IsPartial) {
             context.addError(CompileErrorId.AlreadyDefinedMethod, methodDeclaration, BytecodeHelper.getDisplayName(typeBuilder), name);
             return;
         }
         var partialInfo = partialTypes[typeBuilder.FullName];
         if (!partialInfo.partialMethods.containsKey(methodBuilder)) {
             context.addError(CompileErrorId.AlreadyDefinedMethod, methodDeclaration, BytecodeHelper.getDisplayName(typeBuilder), name);
         }
         var partialMethodInfo = partialInfo.partialMethods[methodBuilder];
         if (methodDeclaration.Body == null) {
             if (partialMethodInfo.definingPart != null) {
                 context.addError(CompileErrorId.MultiplePartialDefiningDeclarations, methodDeclaration);
             }
             partialMethodInfo.definingPart = methodDeclaration;
         } else {
             if (partialMethodInfo.implementingPart != null) {
                 context.addError(CompileErrorId.MultiplePartialImplementingDeclarations, methodDeclaration);
             }
             partialMethodInfo.implementingPart = methodDeclaration;
         }
         setPartialMethodModifiers(methodDeclaration, methodBuilder);
         setMethodConstraints(methodDeclaration.ConstraintsClauses, methodBuilder);
         methodDeclaration.addUserData(methodBuilder);
     } else {
         methodBuilder = typeBuilder.defineMethod(name);
         methodDeclaration.addUserData(methodBuilder);
         setTypeParameters(methodBuilder, methodDeclaration.TypeParameters, methodDeclaration);
         context.MemberResolver.enterMethod(methodBuilder);
         try {
             setMethodModifiers(methodDeclaration, methodBuilder);
             var returnType = CompilerHelper.resolveTypeReference(context, typeBuilder.PackageName, methodDeclaration.ReturnType);
             methodBuilder.setReturnType(returnType);
             var i = 0;
             foreach (var parameter in methodDeclaration.Parameters) {
                 var type = CompilerHelper.resolveTypeReference(context, typeBuilder.PackageName, parameter.Type);
                 var paramBuilder = methodBuilder.addParameter(type);
                 paramBuilder.setName(context.getIdentifier(parameter.NameOffset, parameter.NameLength));
                 if (parameter.Modifier == ParameterModifier.Params) {
                     if (i < methodDeclaration.Parameters.size() - 1) {
                         context.addError(CompileErrorId.ParamsNotLast, parameter);
                     }
                     if (!type.IsArray) {
                         context.addError(CompileErrorId.ParamsNotArray, parameter);
                     }
                     methodBuilder.setVarargs(true);
                 } else if (parameter.Modifier == ParameterModifier.This) {
                     if (!methodBuilder.IsStatic) {
                         context.addError(CompileErrorId.ThisParameterNotStatic, parameter);
                     }
                     if (i > 0) {
                         context.addError(CompileErrorId.ThisNotFirst, parameter);
                     }
                     methodBuilder.addAnnotation(context.getType("stab/lang/ExtensionMethod", parameter), false);
                 }
                 i++;
             }
             setMethodConstraints(methodDeclaration.ConstraintsClauses, methodBuilder);
             if (methodDeclaration.IsPartial) {
                 var partialInfo = partialTypes[typeBuilder.getFullName()];
                 var partialMethodInfo = new PartialMethodInfo();
                 if (methodDeclaration.Body == null) {
                     partialMethodInfo.definingPart = methodDeclaration;
                 } else {
                     partialMethodInfo.implementingPart = methodDeclaration;
                 }
                 partialInfo.partialMethods[methodBuilder] = partialMethodInfo;
             }
         } finally {
             context.MemberResolver.leaveMethod();
         }
     }
 }