Beispiel #1
0
        private TypeSymbol ResolveAtomicNameNodeType(AtomicNameNode atomicNameNode, ISymbolTable symbolTable, Symbol contextSymbol)
        {
            if (atomicNameNode.Parent is GenericNameNode || atomicNameNode.Parent is ArrayTypeNode || atomicNameNode.Parent is MethodDeclarationNode)
            {
                var methodDeclaration = atomicNameNode.FindParent <MethodDeclarationNode>();
                if (methodDeclaration != null && (methodDeclaration?.TypeParameters?.Count ?? 0) > 0)
                {
                    if (contextSymbol is MethodSymbol methodSymbol && methodSymbol.Name == methodDeclaration.Name)
                    {
                        var genericArgument = methodSymbol.GenericArguments.FirstOrDefault(arg => arg.Name == atomicNameNode.Name);
                        if (genericArgument != null)
                        {
                            return(genericArgument);
                        }
                    }

                    for (int i = 0; i < methodDeclaration.TypeParameters.Count; i++)
                    {
                        TypeParameterNode typeParameterNode = (TypeParameterNode)methodDeclaration.TypeParameters[i];
                        if (typeParameterNode.NameNode.Equals(atomicNameNode))
                        {
                            return(new GenericParameterSymbol(i, atomicNameNode.Name, true, GlobalNamespace));
                        }
                    }
                }
            }

            //TODO: Implement Var resolution mechanism here. Need to evaluate the right hand expression of the node, probably needs roslyn
            if (atomicNameNode.Name == "var")
            {
                return(ResolveIntrinsicType(IntrinsicType.Object));
            }

            return(null);
        }
        public DefaultConstantExpression(TypeParameterNode typeParameter)
            : base(typeParameter.RelatedToken)
		{
            this.typeParameter = typeParameter;
		}
Beispiel #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="allowAttributes"> Attributes are authorized in type parameter declaration. 
        /// In closed type and in constraints, attributes are not authorized </param>
        /// <param name="inDeclaration"> in generic type declaration, type parameter are only identifier, and type name are not authorized.
        /// So it is used to reject string like "object", "string", etc ... </param>
        /// <param name="allowEmpty"> In the case of the expression typeof(), empty type parameter are allowed </param>
        private void ParseTypeParameterNode(bool allowAttributes, bool inDeclaration, bool allowEmpty )
        {
            if (curmods != Modifier.Empty)
                ReportError("Type parameter can not contain modifiers");

            ParsePossibleAttributes(false);

            if ( !allowAttributes
                && curAttributes.Count > 0)
            {
                RecoverFromError("Attributes not allowed for the type Parameter", TokenID.Ident);
            }

            TypeParameterNode typeParameter = null;

            // inDeclaration is only used to force the type parameter to be an identifier
            // but, due to developer write errors, it might be a TypeNode ... 
            if (inDeclaration)
            {
                //parse ident only
                // parses all type of type parameter to handle wrong user's syntax 
                // i.e. : the user add a type name in a method generic type parameters declaration.
                // -> it avoid crash
                // one another case is :
                //
                // class kv <k,v> {}
                //
                // class m <k,v> : c <k,v>,
                // {
                //         void a <kv <k,v>>.x () {} // a<t>.x ()
                // }
                // 
                ExpressionNode name = ParseIdentifierOrKeyword(true, true, true, false);
                bool empty = true;

                if ( name != null )
                {
                    if ( name is IdentifierExpression )
                    {
                        IdentifierExpression id = name as IdentifierExpression;
                        empty = id.Identifier == string.Empty; // TODO: ?
                        typeParameter = new TypeParameterNode(id );

                        empty = false;
                    }
                    else
                    {
                        if (name is TypeNode)
                        {
                            TypeNode ty = name as TypeNode;
                            empty = ty.Identifier.QualifiedIdentifier == string.Empty;
                            typeParameter = new TypeParameterNode(ty );

                            empty = false;
                        }
                    }
                }

                if ( empty )
                {
                    ReportError("type parameter must be simple name");
                    typeParameter = new TypeParameterNode(name.RelatedToken);
                }
            }
            else
            {
                //ParseType ...WARNING : it could be a type parameter

                switch (curtok.ID)
                {
                    case TokenID.Comma:
                    case TokenID.Greater:
                    case TokenID.RParen:
                        // we are in the case of empty parameter
                        typeParameter = new TypeParameterNode(curtok);
                        break;
                    default:
                        IType t = ParseType();
                        if (t is TypePointerNode)
                        {
                            ReportError("pointer type are not authorized in generic's type parameters.");
                        }
                        // if t is TypePointerNode, it creates an empty type parameter
                        typeParameter = new TypeParameterNode( t as TypeNode );
                        break;
                }

            }

            ApplyAttributes(typeParameter);

            if (!allowEmpty 
                && typeParameter.IsEmpty )
            {
                ReportError("Empty type parameter not allowed");
            }

            if (!typeParameter.IsEmpty
                    && curTypeParameters.Contains(typeParameter))
            {
                ReportError("duplicated type parameter name");
            }
            else
            {
                curTypeParameters.Add(typeParameter);
            }
        }
        public virtual object VisitTypeParameter(TypeParameterNode typeParameter, object data)
        {
            stackMap.Push(typeParameter);
            typeParameter.Attributes.AcceptVisitor(this, data);
            
            if (typeParameter.Identifier != null)
            {
                typeParameter.Identifier.AcceptVisitor(this, data);
            }

            if (typeParameter.Type != null)
            {
                typeParameter.Type.AcceptVisitor(this, data);
            }

            stackMap.Pop();
            return null;

        }