// 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); } }
// 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); }
// 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 '.' } }
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); }