// Creates the codedom expression for a class variable, and attaches it to the given type. public static void Emit(CodeTypeDeclaration codeTypeDeclaration, ClassVariable classVariable) { var codeField = new CodeMemberField(); codeTypeDeclaration.Members.Add(codeField); codeField.Name = classVariable.Name; codeField.Type = new CodeTypeReference(classVariable.TypeName); // Translate it's accessibility var attr = MemberAttributes.Public; switch(classVariable.Accessibility) { case Accessibility.Internal: attr = MemberAttributes.FamilyAndAssembly; break; case Accessibility.Private: attr = MemberAttributes.Private; break; case Accessibility.Protected: attr = MemberAttributes.Family; break; } // shared = static if (classVariable.IsShared) attr |= MemberAttributes.Static; // Final = const if (classVariable.IsFinal) attr |= MemberAttributes.Const; codeField.Attributes = attr; }
// Build a class variable expression. public static void BuildClassVariable(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { ClassVariable c = new ClassVariable(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(c); // Set default modifiers var p = parentExpression as Class; if (p.IsModule) { c.IsShared = true; } if (p.IsStruct) c.Accessibility = Accessibility.Public; // Interpret declaration modifiers (shared, public, etc). InterpretClassVariableModifiers(root, c, currentNode.ChildNodes[0].ChildNodes[0]); // Treat array type and generic type declarations differently. if (currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].Term.ToString() == "array") { c.TypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()) + "[]"; } else if (currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].Term.ToString() == "generic_identifier") { var genericNode = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0]; c.Name = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText()); c.TypeName = parser.CheckAlias(genericNode.ChildNodes[0].FindTokenAndGetText()) + "<"; for (int n = 0; n < genericNode.ChildNodes[2].ChildNodes.Count; n++) { c.TypeName += parser.CheckAlias(genericNode.ChildNodes[2].ChildNodes[n].FindTokenAndGetText()); if (n < genericNode.ChildNodes[2].ChildNodes.Count - 1) c.TypeName += ","; } c.TypeName += ">"; } else c.TypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].FindTokenAndGetText()); // Get the variable name. c.Name = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText(); }
// Interpret class variable declaration modifiers: make sure to check for duplicates or conflicting ones. static void InterpretClassVariableModifiers(Root root, ClassVariable c, ParseTreeNode node) { bool foundPublic = false; bool foundInternal = false; bool foundShared = false; bool foundPrivate = false; bool foundProtected = false; bool foundFinal = false; foreach (var modifierNode in node.ChildNodes) { string text = modifierNode.FindTokenAndGetText(); if (text == "public") { if (foundPublic || foundInternal || foundPrivate || foundProtected) { root.CompilerErrors.Add(new MultipleAccessModifiersCompilerError("", modifierNode.FindToken().Location.Line, modifierNode.FindToken().Location.Position)); } else { c.Accessibility = Accessibility.Public; foundPublic = true; } } if (text == "internal") { if (foundInternal || foundPublic || foundPrivate || foundProtected) { root.CompilerErrors.Add(new MultipleAccessModifiersCompilerError("", modifierNode.FindToken().Location.Line, modifierNode.FindToken().Location.Position)); } else { c.Accessibility = Accessibility.Internal; foundInternal = true; } } if (text == "protected") { if (foundInternal || foundPublic || foundPrivate || foundProtected) { root.CompilerErrors.Add(new MultipleAccessModifiersCompilerError("", modifierNode.FindToken().Location.Line, modifierNode.FindToken().Location.Position)); } else { c.Accessibility = Accessibility.Protected; foundProtected = true; } } if (text == "private") { if (foundInternal || foundPublic || foundPrivate || foundProtected) { root.CompilerErrors.Add(new MultipleAccessModifiersCompilerError("", modifierNode.FindToken().Location.Line, modifierNode.FindToken().Location.Position)); } else { c.Accessibility = Accessibility.Private; foundPrivate = true; } } if (text == "final") { if (foundFinal) { root.CompilerErrors.Add(new DuplicateModifiersCompilerError("", modifierNode.FindToken().Location.Line, modifierNode.FindToken().Location.Position)); } else { c.IsFinal = true; foundFinal = true; } } if (text == "shared") { if (foundShared) { root.CompilerErrors.Add(new DuplicateModifiersCompilerError("", modifierNode.FindToken().Location.Line, modifierNode.FindToken().Location.Position)); } else { c.IsShared = true; foundShared = true; } } } }