Пример #1
0
        // ClassType
        private void DoClassType()
        {
            LexToken firstClassToken = InputList.CurrentToken();
            Type     thisClassType   = null;

            try {
                thisClassType = Parser.ParseType(InputList, true, false, BindingFlags.Public);
            } catch (Exception ex) {
                InputList.ThrowException("The type of this class needs to be the same as a real C# class in the hosting program.");
            }
            if (ClassType != null && thisClassType != ClassType)
            {
                firstClassToken.ThrowException("The class type must be the same as the previous one '" + ClassType.Name + "'", InputList);
            }
            ClassType = thisClassType;

            if (ClassType.IsValueType)
            {
                firstClassToken.ThrowException("Cannot use a value type for the class.", InputList);
            }
            if (ClassType.IsAbstract && ClassType.IsSealed)
            {
                firstClassToken.ThrowException("Cannot use a static class here.", InputList);
            }
            if (ClassType.IsEnum)
            {
                firstClassToken.ThrowException("Cannot use a Enum type here.", InputList);
            }
            if (!ClassType.IsClass)
            {
                firstClassToken.ThrowException("Must use a class type here.", InputList);
            }
        }
Пример #2
0
        // Syntax:
        // Member  = '.' StaticMember .
        public ExpState ParseMember(Type theClass, LexList list, BindingFlags flags, bool implicitDot)
        {
            if (!implicitDot)
            {
                list.CheckStrAndAdvance(".", "Expected a dot followed by a static member name here.");
            }
            LexToken token = list.CurrentToken();
            string   name  = list.GetIdentifier("Expected the name of a static member here.");

            FieldInfo fi = theClass.GetField(name, flags);

            if (fi != null)
            {
                return(new ExpState(fi));
            }

            list.Prev();
            return(null);
        }
Пример #3
0
        // Syntax:
        // Type               =  TypeNonArray [ TypeArrayPart ] .
        // TypeNonArray       =  TypeIdAndGenerics *( '.' TypeIdAndGenerics ) .
        // TypeIdAndGenerics  =  TypeIdentifier [ Generics ] .
        // Generics           =  '<' Type *( ',' Type ) '>' .
        // TypeArrayPart      =  '[' ']' *( '[' ']' ) .

        public Type Parse(LexList list, bool typeOnly, bool arrayIndexActualsAllowed, out bool pendingCloseAngle, BindingFlags visibility)
        {
            string id         = "";
            Type   returnType = null;
            int    checkPoint = list.Index;

            pendingCloseAngle = false;

            while (true)
            {
                if (list.Kind == LexKind.Type)
                {
                    returnType = list.CurrentToken().ActualObject as Type;
                    list.Next();
                    return(returnType);
                }
                if (list.Kind != LexKind.Identifier)
                {
                    if (typeOnly)
                    {
                        list.ThrowException("Unable to convert this to a type.");
                    }
                    return(returnType);
                }
                if (id != "")
                {
                    id += ".";
                }
                id += list.GetIdentifier();
                Type ty = null;
                if (list.Str != "<" || !IsGenericSpec(list))
                {
                    ty = FindTypeFromDottedIds(returnType, id, visibility);
                }
                if (ty != null)
                {
                    id         = "";
                    returnType = ty;
                    checkPoint = list.Index;
                    if (list.Kind == LexKind.End)
                    {
                        return(returnType);
                    }
                    if (list.Str != ".")
                    {
                        return(ParseArrayTypeModifier(list, returnType, arrayIndexActualsAllowed));
                    }
                }
                else if (ty == null && list.Str == "<" && IsGenericSpec(list))
                {
                    // The test for the GenericSpec is needed to separate out comparision '<' or shift '<' from generic brackets.
                    int    save  = list.Index;
                    Type[] types = ParseGenericTypeModifier(list, out pendingCloseAngle, visibility);
                    id += "`" + types.Length.ToString();
                    ty  = FindTypeFromDottedIds(returnType, id, visibility);
                    if (ty != null)
                    {
                        ty = ty.MakeGenericType(types.ToArray());
                    }
                    if (ty == null)
                    {
                        if (typeOnly)
                        {
                            list[save].ThrowException("Unable to resolve generic type.", list);
                        }
                        list.Index = checkPoint;
                        return(returnType);
                    }
                    return(ParseArrayTypeModifier(list, ty, arrayIndexActualsAllowed));
                }
                else
                {
                    if (list.Str != ".")
                    {
                        if (typeOnly)
                        {
                            list.Prev(); list.ThrowException("Unable to convert this to a type.");
                        }
                        list.Index = checkPoint;
                        return(returnType);
                    }
                }
                list.Next(); // skips over the '.'
            }
        }
Пример #4
0
        public MakeClass AddMethodsAndFields(LexList list, bool overwriteAllowed)
        {
            if (InputList != null)
            {
                PreviousInputLists.Add(InputList);
            }
            InputList = list;
            Type varType = null;
            var  currentListOfMethods = new List <CompileMethod>();

            try {
                Crosslink();
                DoClassVisibility();
                DoClassType();
                InputList.CheckStrAndAdvance("{", "Expected an { after the class header.");
                while (true)
                {
                    if (InputList.Str == "}" && InputList.NextIsAtEnd())
                    {
                        break;
                    }
                    else if ((InputList.Str == "public" || InputList.Str == "private" || InputList.Str == "[") && !IsAFieldDefinition())
                    {
                        CompileNextMethodHeader(InputList, overwriteAllowed, currentListOfMethods);
                    }
                    else if ((InputList.Str == "public" || InputList.Str == "private") && IsAFieldDefinition())
                    {
                        InputList.Next();
                        varType = IsVarKind();
                        if (varType == null)
                        {
                            InputList.ThrowException("Unknown field type here");
                        }
                        CompileNextFieldDefinition(InputList, varType);
                    }
                    else if ((varType = IsVarKind()) != null)
                    {
                        CompileNextFieldDefinition(InputList, varType);
                    }
                    else
                    {
                        InputList.ThrowException("Expected either a 'public' or 'private' keyword (to start a method) or a type (to start a field declaration) here or the closing } of the class.");
                    }
                }
                InputList.CheckStrAndAdvance("}", "Expected a closing } here.");
                if (!InputList.AtEnd())
                {
                    InputList.ThrowException("Expected the end of the source text here.");
                }
                if (MadeFieldsDict.Count > 0)
                {
                    MakeFieldInitialiser(currentListOfMethods);
                }
                FinishClass(currentListOfMethods);
            } catch (LexListException lle) {
                throw lle;
            } catch (Exception ex) {
                list.CurrentToken().ThrowException(ex.Message, list);
            }
            return(this);
        }