コード例 #1
0
        public static ICollection <IReference> Decompose(this IClass scope, IReference reference)
        {
            var layering = Layering <IClass> .CreateLayers(scope, cl => cl.BaseTypes);

            var references = new HashSet <IReference>();

            references.Add(reference);
            foreach (var layer in layering)
            {
                if (layer.Count > 1)
                {
                    throw new InvalidOperationException("There is a cycle in the inheritance hierarchy.");
                }
                foreach (var cl in layer)
                {
                    foreach (var r in cl.References)
                    {
                        if (r.Refines != null && references.Contains(r.Refines))
                        {
                            references.Add(r);
                        }
                    }
                }
            }
            return(references);
        }
コード例 #2
0
 private string QueryResult()
 {
     return(string.Join('|', (from comment in SocialNetwork.Descendants().OfType <Comment>()
                              let layering = Layering <IUser> .CreateLayers(comment.LikedBy, u => u.Friends.Where(f => f.Likes.Contains(comment)))
                                             orderby layering.Sum(l => Square(l.Count))
                                             select comment.Id).Take(3)));
 }
コード例 #3
0
 private string QueryResult()
 {
     return(string.Join('|', (from comment in SocialNetwork.Descendants().OfType <Comment>()
                              let layering = Layering <IUser> .CreateLayers(comment.LikedBy, u => u.Friends.Intersect(comment.LikedBy))
                                             let score = layering.Sum(l => Square(l.Count))
                                                         orderby(score, comment.Timestamp) descending
                                                         select comment.Id).Take(3)));
 }
コード例 #4
0
 public IEnumerator <IEnumerable <T> > GetEnumerator()
 {
     if (components == null)
     {
         components = Layering <T> .CreateLayers(nodes, edges);
     }
     return(components.GetEnumerator());
 }
コード例 #5
0
        protected virtual void ResolveMultipleInheritanceMembers(CodeTypeDeclaration generatedType, HashSet <CodeTypeMember> shadows, CodeConstructor constructor)
        {
            Func <CodeTypeDeclaration, IEnumerable <CodeTypeDeclaration> > getBaseTypes =
                type => {
                var interfaceType = CodeDomHelper.GetOrCreateUserItem <CodeTypeDeclaration>(type, CodeDomHelper.InterfaceKey);
                if (interfaceType == null)
                {
                    interfaceType = type;
                }
                return(interfaceType.BaseTypes.Cast <CodeTypeReference>().Select(r => r.GetTypeForReference()).Where(c => c != null));
            };
            var layering = Layering <CodeTypeDeclaration> .CreateLayers(generatedType, getBaseTypes);

            CodeTypeDeclaration implBaseType = FindBaseClassAndCreateShadows(generatedType, shadows, layering);
            IEnumerable <CodeTypeDeclaration> inheritedBaseClasses;

            if (implBaseType != null)
            {
                inheritedBaseClasses = implBaseType.Closure(getBaseTypes);
                var implementationRef = new CodeTypeReference();
                implementationRef.BaseType = implBaseType.Name;
                var n = implBaseType.GetReferenceForType().Namespace();
                if (n != null && n.EndsWith(implBaseType.Name))
                {
                    implementationRef.BaseType = n + "." + implBaseType.Name;
                }
                else
                {
                    implementationRef.SetNamespace(n);
                }
                generatedType.BaseTypes.Insert(0, implementationRef);
            }
            else
            {
                inheritedBaseClasses = Enumerable.Empty <CodeTypeDeclaration>();
                AddImplementationBaseClass(generatedType);
            }
            for (int i = layering.Count - 1; i >= 0; i--)
            {
                foreach (var baseType in layering[i])
                {
                    if (!inheritedBaseClasses.Contains(baseType) &&
                        baseType != generatedType &&
                        ShouldContainMembers(generatedType, baseType.GetReferenceForType()))
                    {
                        var dependent = baseType.DependentMembers(false);
                        if (dependent != null)
                        {
                            foreach (var inheritedMember in dependent)
                            {
                                RecursivelyAddDependentMembers(generatedType.Members, constructor.Statements, inheritedMember, shadows);
                            }
                        }
                    }
                }
            }
        }
コード例 #6
0
            private void Recompute()
            {
                components.Clear();
                var layers = Layering <T> .CreateLayers(nodes, GetEdges);

                foreach (var layer in layers)
                {
                    foreach (var item in layer)
                    {
                        components.Add(item, layer);
                    }
                }
                OnCleared();
            }
コード例 #7
0
            private static IEClass FindBaseClass(IEClass eClass, out IEnumerable <IEStructuralFeature> shadows)
            {
                shadows = Enumerable.Empty <IEStructuralFeature>();
                var ancestors = eClass.Closure(c => c.ESuperTypes);

                foreach (var layer in Layering <IEClass> .CreateLayers(eClass, c => Edges(c, ancestors)).Reverse())
                {
                    if (layer.Count == 1 && layer.First() != eClass && !shadows.IntersectsWith(AllFeatures(layer.First())))
                    {
                        return(layer.First());
                    }
                    foreach (var cl in layer)
                    {
                        shadows = shadows.Union(Refinements(cl));
                    }
                }
                return(null);
            }
コード例 #8
0
            public override void Transform(IClass scope, IReference reference, CodeMemberProperty property, Transformations.Core.ITransformationContext context)
            {
                var baseTypes = Layering <IClass> .CreateLayers(scope, c => c.BaseTypes).Select(c => c.Single()).ToList();

                if (!baseTypes.Contains((IClass)reference.DeclaringType))
                {
                    throw new InvalidOperationException(string.Format("The reference {0} cannot be refined in the scope of class {1} because {1} does not inherit from its declaring class.", reference.Name, scope.Name));
                }

                var classDeclaration  = context.Trace.ResolveIn(Rule <Type2Type>(), scope);
                var originalReference = context.Trace.ResolveIn(Rule <Reference2Property>(), reference);

                property.Attributes = MemberAttributes.Private;
                property.Name       = originalReference.Name;
                property.PrivateImplementationType = CreateReference(reference.DeclaringType, false, context);
                property.Type = originalReference.Type;

                lock (classDeclaration)
                {
                    classDeclaration.Shadows(true).Add(originalReference);
                    classDeclaration.DependentMembers(true).Add(property);
                }

                var implementations = baseTypes.SelectMany(s => s.References).Where(r => r.Refines == reference).ToList();
                var constraints     = baseTypes.SelectMany(s => s.ReferenceConstraints).Where(rc => rc.Constrains == reference);

                foreach (var declClass in implementations.Select(a => a.DeclaringType).OfType <IClass>().Concat(constraints.Select(c => c.DeclaringType)).Distinct())
                {
                    if (declClass != scope)
                    {
                        var refinedReference = context.Trace.ResolveIn(this, declClass, reference);
                        if (refinedReference != null)
                        {
                            property.Shadows(true).Add(refinedReference);
                        }
                    }
                }

                if (implementations.Count == 0 && !constraints.Any())
                {
                    throw new InvalidOperationException(
                              string.Format("The reference {0} can not be refined in the scope of class {1} because no reference refines it. ", reference, scope)
                              );
                }

                var referenceType = CreateReference(reference.Type, true, context);

                if (reference.UpperBound == 1)
                {
                    var nullRef = new CodePrimitiveExpression(null);
                    if (!constraints.Any())
                    {
                        var castedThisVariable    = new CodeVariableDeclarationStatement(classDeclaration.GetReferenceForType(), "_this", new CodeThisReferenceExpression());
                        var castedThisVariableRef = new CodeVariableReferenceExpression("_this");
                        property.GetStatements.Add(castedThisVariable);
                        property.SetStatements.Add(castedThisVariable);
                        var setRef = new CodePropertySetValueReferenceExpression();
                        var ifNull = new CodeConditionStatement();
                        ifNull.Condition = new CodeBinaryOperatorExpression(setRef, CodeBinaryOperatorType.IdentityInequality, nullRef);
                        var foundMatch = false;

                        foreach (var implementation in implementations)
                        {
                            var implementationRef = new CodePropertyReferenceExpression(castedThisVariableRef, context.Trace.ResolveIn(Rule <Reference2Property>(), implementation).Name);

                            if (implementation.Type == reference.Type)
                            {
                                property.GetStatements.Add(new CodeMethodReturnStatement(implementationRef));
                                property.SetStatements.Add(new CodeAssignStatement(implementationRef, setRef));
                                foundMatch = true;
                                break;
                            }
                            else
                            {
                                var getIfStmt = new CodeConditionStatement();
                                getIfStmt.Condition = new CodeBinaryOperatorExpression(implementationRef, CodeBinaryOperatorType.IdentityInequality, nullRef);
                                getIfStmt.TrueStatements.Add(new CodeMethodReturnStatement(implementationRef));
                                property.GetStatements.Add(getIfStmt);

                                var implementationType = CreateReference(implementation.Type, true, context);
                                var asRef       = new CodeMethodReferenceExpression(setRef, "As", implementationType);
                                var localVar    = new CodeVariableDeclarationStatement(implementationType, "__" + implementation.Name, new CodeMethodInvokeExpression(asRef));
                                var localVarRef = new CodeVariableReferenceExpression(localVar.Name);
                                var setIfStmt   = new CodeConditionStatement();
                                setIfStmt.Condition = new CodeBinaryOperatorExpression(localVarRef, CodeBinaryOperatorType.IdentityInequality, nullRef);
                                setIfStmt.TrueStatements.Add(new CodeAssignStatement(implementationRef, localVarRef));
                                setIfStmt.TrueStatements.Add(new CodeMethodReturnStatement());
                                ifNull.TrueStatements.Add(localVar);
                                ifNull.TrueStatements.Add(setIfStmt);
                                ifNull.FalseStatements.Add(new CodeAssignStatement(implementationRef, nullRef));
                            }
                        }
                        ifNull.FalseStatements.Add(new CodeMethodReturnStatement());

                        if (ifNull.TrueStatements.Count > 0)
                        {
                            property.SetStatements.Add(ifNull);
                        }

                        if (!foundMatch)
                        {
                            property.GetStatements.Add(new CodeMethodReturnStatement(nullRef));
                            property.SetStatements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(System.ArgumentException), new CodePrimitiveExpression("There was no suitable refining reference found for this object"))));
                        }
                    }
                    else
                    {
                        var constraint   = constraints.Last();
                        var ifNotDefault = new CodeConditionStatement();
                        ifNotDefault.TrueStatements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(System.NotSupportedException))));
                        CodeExpression value;
                        if (constraint.References.Count == 0)
                        {
                            value = nullRef;
                        }
                        else
                        {
                            var refEl = constraint.References[0];
                            var uri   = refEl.AbsoluteUri;
                            if (uri == null)
                            {
                                throw new System.InvalidOperationException();
                            }
                            var metaRepositoryInstance = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(MetaRepository)), "Instance");
                            var refElExpression        = new CodeMethodInvokeExpression(metaRepositoryInstance, "Resolve", new CodePrimitiveExpression(uri.AbsoluteUri));
                            refElExpression = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(refElExpression, "As", property.Type));

                            var retrieveValueMethod = new CodeMemberMethod
                            {
                                Name       = "Retrieve" + reference.Name.ToPascalCase(),
                                Attributes = MemberAttributes.Private | MemberAttributes.Static,
                                ReturnType = property.Type
                            };
                            retrieveValueMethod.Statements.Add(new CodeMethodReturnStatement(refElExpression));
                            property.DependentMembers(true).Add(retrieveValueMethod);

                            var staticField = new CodeMemberField(new CodeTypeReference("Lazy", property.Type), "_" + reference.Name.ToPascalCase());
                            staticField.Attributes     = MemberAttributes.Private | MemberAttributes.Static;
                            staticField.InitExpression = new CodeObjectCreateExpression(staticField.Type, new CodeMethodReferenceExpression(null, retrieveValueMethod.Name));
                            property.DependentMembers(true).Add(staticField);
                            value = new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(null, staticField.Name), "Value");
                        }
                        property.GetStatements.Add(new CodeMethodReturnStatement(value));
                        ifNotDefault.Condition = new CodeBinaryOperatorExpression(new CodePropertySetValueReferenceExpression(), CodeBinaryOperatorType.IdentityInequality, value);
                        property.SetStatements.Add(ifNotDefault);
                    }

                    CreateChangeEvent(property, implementations, context, "Changed");
                    CreateChangeEvent(property, implementations, context, "Changing");
                }
                else
                {
                    if (reference.IsUnique)
                    {
                        throw new System.InvalidOperationException("Unique references must not be refined!");
                    }

                    if (implementations.Count > 0 || constraints.Any(c => c.References.Any()))
                    {
                        var collectionType = context.Trace.ResolveIn(Rule <RefinedReferenceCollectionClassGenerator>(), scope, reference);
                        property.GetStatements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(collectionType.GetReferenceForType(), new CodeThisReferenceExpression())));
                        property.DependentTypes(true).Add(collectionType);
                    }
                    else
                    {
                        property.GetStatements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(new CodeTypeReference(typeof(EmptyList <>).Name, referenceType)), "Instance")));
                    }
                }
            }
コード例 #9
0
ファイル: ClassGenerator.cs プロジェクト: lukeIam/NMF
        protected virtual void ResolveMultipleInheritanceMembers(CodeTypeDeclaration generatedType, HashSet <CodeTypeMember> shadows, CodeConstructor constructor)
        {
            var allClasses = generatedType.Closure(GetBaseClasses);
            var layering   = Layering <CodeTypeDeclaration> .CreateLayers(generatedType, c => Edges(c, allClasses));

            CodeTypeDeclaration implBaseType = null;
            int layerIndex;

            for (layerIndex = layering.Count - 1; layerIndex >= 0; layerIndex--)
            {
                var layer = layering[layerIndex];
                if (layer.Count == 1 && layer.First() != generatedType && !shadows.IntersectsWith(AllFeatures(layer.First())))
                {
                    implBaseType = layer.First();
                    break;
                }
                foreach (var cl in layer)
                {
                    shadows.UnionWith(Refinements(cl));
                }
            }
            IEnumerable <CodeTypeDeclaration> inheritedBaseClasses;

            if (implBaseType != null)
            {
                inheritedBaseClasses = layering.Take(layerIndex + 1).SelectMany(s => s);
                var implementationRef = new CodeTypeReference();
                implementationRef.BaseType = implBaseType.Name;
                var n = implBaseType.GetReferenceForType().Namespace();
                if (n != null && n.EndsWith(implBaseType.Name))
                {
                    implementationRef.BaseType = n + "." + implBaseType.Name;
                }
                else
                {
                    implementationRef.SetNamespace(n);
                }
                generatedType.BaseTypes.Insert(0, implementationRef);
            }
            else
            {
                inheritedBaseClasses = Enumerable.Empty <CodeTypeDeclaration>();
                AddImplementationBaseClass(generatedType);
            }
            CodeDomHelper.SetUserItem(generatedType, CodeDomHelper.BaseClassesKey, inheritedBaseClasses);
            for (int i = layerIndex + 1; i < layering.Count; i++)
            {
                foreach (var baseType in layering[i])
                {
                    if (baseType != generatedType)
                    {
                        var dependent = baseType.DependentMembers(false);
                        if (dependent != null)
                        {
                            foreach (var inheritedMember in dependent)
                            {
                                RecursivelyAddDependentMembers(generatedType.Members, constructor.Statements, inheritedMember, shadows);
                            }
                        }
                    }
                }
            }
        }
コード例 #10
0
            /// <summary>
            /// Initializes the generated code property for the refined attribute
            /// </summary>
            /// <param name="scope">The scope in which the attribute is refined</param>
            /// <param name="attribute">The NMeta attribute that is refined</param>
            /// <param name="property">The generated code property</param>
            /// <param name="context">The transformation context</param>
            public override void Transform(IClass scope, IAttribute attribute, CodeMemberProperty property, ITransformationContext context)
            {
                var baseTypes = Layering <IClass> .CreateLayers(scope, c => c.BaseTypes).Select(c => c.Single()).ToList();

                if (!baseTypes.Contains((IClass)attribute.DeclaringType))
                {
                    throw new InvalidOperationException(string.Format("The attribute {0} cannot be refined in the scope of class {1} because {1} does not inherit from its declaring class.", attribute.Name, scope.Name));
                }

                var classDeclaration  = context.Trace.ResolveIn(Rule <Type2Type>(), scope);
                var originalAttribute = context.Trace.ResolveIn(Rule <Attribute2Property>(), attribute);

                property.Attributes = MemberAttributes.Private;
                property.Name       = originalAttribute.Name;
                property.PrivateImplementationType = CreateReference(attribute.DeclaringType, false, context);

                lock (classDeclaration)
                {
                    classDeclaration.Shadows(true).Add(originalAttribute);
                    classDeclaration.DependentMembers(true).Add(property);
                }

                var implementations = baseTypes.SelectMany(s => s.Attributes).Where(att => att.Refines == attribute).ToList();
                var constraints     = baseTypes.SelectMany(s => s.AttributeConstraints).Where(rc => rc.Constrains == attribute);

                foreach (var declClass in implementations.Select(a => a.DeclaringType).OfType <IClass>().Concat(constraints.Select(c => c.DeclaringType)).Distinct())
                {
                    if (declClass != scope)
                    {
                        var refinedAttribute = context.Trace.ResolveIn(this, declClass, attribute);
                        if (refinedAttribute != null)
                        {
                            property.Shadows(true).Add(refinedAttribute);
                        }
                    }
                }

                if (implementations.Count == 0 && !constraints.Any())
                {
                    throw new InvalidOperationException(
                              string.Format("The attribute {0} can not be refined in the scope of class {1} because no reference refines it. ", attribute, scope)
                              );
                }

                var attributeType = CreateReference(attribute.Type, false, context);

                if (attribute.UpperBound == 1)
                {
                    property.Type = attributeType;

                    if (implementations.Count > 1)
                    {
                        throw new System.InvalidOperationException("A single value typed attribute may only be refined once!");
                    }
                    else if (implementations.Count == 1)
                    {
                        if (constraints.Any())
                        {
                            throw new System.InvalidOperationException("A single values attribute must not be constrained and implemented at the same time!");
                        }
                        if (implementations[0].Type != attribute.Type)
                        {
                            throw new System.InvalidOperationException("The refining attribute has a different type than the original attribute. Covariance is not supported for attributes!");
                        }

                        var castedThisVariable    = new CodeVariableDeclarationStatement(classDeclaration.GetReferenceForType(), "_this", new CodeThisReferenceExpression());
                        var castedThisVariableRef = new CodeVariableReferenceExpression("_this");
                        property.GetStatements.Add(castedThisVariable);
                        property.SetStatements.Add(castedThisVariable);

                        var            implProperty      = context.Trace.ResolveIn(Rule <Attribute2Property>(), implementations[0]);
                        CodeExpression implementationRef = new CodePropertyReferenceExpression(castedThisVariableRef, implProperty.Name);

                        property.GetStatements.Add(new CodeMethodReturnStatement(implementationRef));
                        property.SetStatements.Add(new CodeAssignStatement(implementationRef, new CodePropertySetValueReferenceExpression()));
                    }
                    else
                    {
                        var constraint   = constraints.Last();
                        var ifNotDefault = new CodeConditionStatement();
                        ifNotDefault.TrueStatements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(System.NotSupportedException))));
                        CodeExpression value;
                        if (constraints.Sum(c => c.Values.Count) == 0)
                        {
                            value = new CodeDefaultValueExpression(attributeType);
                        }
                        else
                        {
                            value = CodeDomHelper.CreatePrimitiveExpression(constraint.Values[0], attributeType, attribute.Type is IEnumeration);
                            if (value == null)
                            {
                                throw new InvalidOperationException(string.Format("The value {0} could not be serialized as a value for {1}", constraint.Values[0], attribute));
                            }
                        }
                        property.GetStatements.Add(new CodeMethodReturnStatement(value));
                        ifNotDefault.Condition = new CodeBinaryOperatorExpression(new CodePropertySetValueReferenceExpression(), CodeBinaryOperatorType.IdentityInequality, value);
                        property.SetStatements.Add(ifNotDefault);
                    }

                    CreateChangeEvent(property, implementations, context, "Changed");
                    CreateChangeEvent(property, implementations, context, "Changing");
                }
                else
                {
                    if (attribute.IsUnique)
                    {
                        throw new System.InvalidOperationException("Unique attributes must not be refined.");
                    }

                    if (implementations.Count > 0 || constraints.Any(c => c.Values.Any()))
                    {
                        var collectionType = context.Trace.ResolveIn(Rule <RefinedAttributeCollectionClassGenerator>(), scope, attribute);
                        property.GetStatements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(collectionType.GetReferenceForType(), new CodeThisReferenceExpression())));
                        property.DependentTypes(true).Add(collectionType);
                    }
                    else
                    {
                        property.GetStatements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(new CodeTypeReference(typeof(EmptyList <>).Name, attributeType)), "Instance")));
                    }
                }
            }