|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CodeDom.Compiler
{
using System.Runtime.InteropServices;
using System.Diagnostics;
using System;
using Microsoft.Win32;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Globalization;
using Microsoft.CodeDom;
using System.Text;
/// <devdoc>
/// <para>Provides a base class for code generators.</para>
/// </devdoc>
public abstract class CodeGenerator : ICodeGenerator
{
private const int ParameterMultilineThreshold = 15;
private IndentedTextWriter _output;
private CodeGeneratorOptions _options;
private CodeTypeDeclaration _currentClass;
private CodeTypeMember _currentMember;
private bool _inNestedBinary = false;
/// <devdoc>
/// <para>
/// Gets the current class.
/// </para>
/// </devdoc>
protected CodeTypeDeclaration CurrentClass
{
get
{
return _currentClass;
}
}
/// <devdoc>
/// <para>
/// Gets or sets the current class name.
/// </para>
/// </devdoc>
protected string CurrentTypeName
{
get
{
if (_currentClass != null)
{
return _currentClass.Name;
}
return "<% unknown %>";
}
}
/// <devdoc>
/// <para>
/// Gets or sets the current member of the class.
/// </para>
/// </devdoc>
protected CodeTypeMember CurrentMember
{
get
{
return _currentMember;
}
}
/// <devdoc>
/// <para>
/// Gets or sets the current member name.
/// </para>
/// </devdoc>
protected string CurrentMemberName
{
get
{
if (_currentMember != null)
{
return _currentMember.Name;
}
return "<% unknown %>";
}
}
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the current object being
/// generated is an interface.
/// </para>
/// </devdoc>
protected bool IsCurrentInterface
{
get
{
if (_currentClass != null && !(_currentClass is CodeTypeDelegate))
{
return _currentClass.IsInterface;
}
return false;
}
}
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the current object being generated
/// is a class.
/// </para>
/// </devdoc>
protected bool IsCurrentClass
{
get
{
if (_currentClass != null && !(_currentClass is CodeTypeDelegate))
{
return _currentClass.IsClass;
}
return false;
}
}
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the current object being generated
/// is a struct.
/// </para>
/// </devdoc>
protected bool IsCurrentStruct
{
get
{
if (_currentClass != null && !(_currentClass is CodeTypeDelegate))
{
return _currentClass.IsStruct;
}
return false;
}
}
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the current object being generated
/// is an enumeration.
/// </para>
/// </devdoc>
protected bool IsCurrentEnum
{
get
{
if (_currentClass != null && !(_currentClass is CodeTypeDelegate))
{
return _currentClass.IsEnum;
}
return false;
}
}
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the current object being generated
/// is a delegate.
/// </para>
/// </devdoc>
protected bool IsCurrentDelegate
{
get
{
if (_currentClass != null && _currentClass is CodeTypeDelegate)
{
return true;
}
return false;
}
}
/// <devdoc>
/// <para>
/// Gets or sets the amount of spaces to indent.
/// </para>
/// </devdoc>
protected int Indent
{
get
{
return _output.Indent;
}
set
{
_output.Indent = value;
}
}
/// <devdoc>
/// <para>
/// Gets the token that represents <see langword='null'/>.
/// </para>
/// </devdoc>
protected abstract string NullToken { get; }
/// <devdoc>
/// <para>
/// Gets or sets the System.IO.TextWriter
/// to use for output.
/// </para>
/// </devdoc>
protected TextWriter Output
{
get
{
return _output;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected CodeGeneratorOptions Options
{
get
{
return _options;
}
}
private void GenerateType(CodeTypeDeclaration e)
{
_currentClass = e;
if (e.StartDirectives.Count > 0)
{
GenerateDirectives(e.StartDirectives);
}
GenerateCommentStatements(e.Comments);
if (e.LinePragma != null) GenerateLinePragmaStart(e.LinePragma);
GenerateTypeStart(e);
if (Options.VerbatimOrder)
{
foreach (CodeTypeMember member in e.Members)
{
GenerateTypeMember(member, e);
}
}
else
{
GenerateFields(e);
GenerateSnippetMembers(e);
GenerateTypeConstructors(e);
GenerateConstructors(e);
GenerateProperties(e);
GenerateEvents(e);
GenerateMethods(e);
GenerateNestedTypes(e);
}
// Nested types clobber the current class, so reset it.
_currentClass = e;
GenerateTypeEnd(e);
if (e.LinePragma != null) GenerateLinePragmaEnd(e.LinePragma);
if (e.EndDirectives.Count > 0)
{
GenerateDirectives(e.EndDirectives);
}
}
protected virtual void GenerateDirectives(CodeDirectiveCollection directives)
{
}
private void GenerateTypeMember(CodeTypeMember member, CodeTypeDeclaration declaredType)
{
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
if (member is CodeTypeDeclaration)
{
((ICodeGenerator)this).GenerateCodeFromType((CodeTypeDeclaration)member, _output.InnerWriter, _options);
// Nested types clobber the current class, so reset it.
_currentClass = declaredType;
// For nested types, comments and line pragmas are handled separately, so return here
return;
}
if (member.StartDirectives.Count > 0)
{
GenerateDirectives(member.StartDirectives);
}
GenerateCommentStatements(member.Comments);
if (member.LinePragma != null)
{
GenerateLinePragmaStart(member.LinePragma);
}
if (member is CodeMemberField)
{
GenerateField((CodeMemberField)member);
}
else if (member is CodeMemberProperty)
{
GenerateProperty((CodeMemberProperty)member, declaredType);
}
else if (member is CodeMemberMethod)
{
if (member is CodeConstructor)
{
GenerateConstructor((CodeConstructor)member, declaredType);
}
else if (member is CodeTypeConstructor)
{
GenerateTypeConstructor((CodeTypeConstructor)member);
}
else if (member is CodeEntryPointMethod)
{
GenerateEntryPointMethod((CodeEntryPointMethod)member, declaredType);
}
else
{
GenerateMethod((CodeMemberMethod)member, declaredType);
}
}
else if (member is CodeMemberEvent)
{
GenerateEvent((CodeMemberEvent)member, declaredType);
}
else if (member is CodeSnippetTypeMember)
{
// Don't indent snippets, in order to preserve the column
// information from the original code. This improves the debugging
// experience.
int savedIndent = Indent;
Indent = 0;
GenerateSnippetMember((CodeSnippetTypeMember)member);
// Restore the indent
Indent = savedIndent;
// Generate an extra new line at the end of the snippet.
// If the snippet is comment and this type only contains comments.
// The generated code will not compile.
Output.WriteLine();
}
if (member.LinePragma != null)
{
GenerateLinePragmaEnd(member.LinePragma);
}
if (member.EndDirectives.Count > 0)
{
GenerateDirectives(member.EndDirectives);
}
}
private void GenerateTypeConstructors(CodeTypeDeclaration e)
{
IEnumerator en = e.Members.GetEnumerator();
while (en.MoveNext())
{
if (en.Current is CodeTypeConstructor)
{
_currentMember = (CodeTypeMember)en.Current;
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
if (_currentMember.StartDirectives.Count > 0)
{
GenerateDirectives(_currentMember.StartDirectives);
}
GenerateCommentStatements(_currentMember.Comments);
CodeTypeConstructor imp = (CodeTypeConstructor)en.Current;
if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma);
GenerateTypeConstructor(imp);
if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma);
if (_currentMember.EndDirectives.Count > 0)
{
GenerateDirectives(_currentMember.EndDirectives);
}
}
}
}
/// <devdoc>
/// <para> Generates code for the namepsaces in the specifield CodeDom compile unit.
/// </para>
/// </devdoc>
protected void GenerateNamespaces(CodeCompileUnit e)
{
foreach (CodeNamespace n in e.Namespaces)
{
((ICodeGenerator)this).GenerateCodeFromNamespace(n, _output.InnerWriter, _options);
}
}
/// <devdoc>
/// <para> Generates code for the specified CodeDom namespace representation and the classes it
/// contains.</para>
/// </devdoc>
protected void GenerateTypes(CodeNamespace e)
{
foreach (CodeTypeDeclaration c in e.Types)
{
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
((ICodeGenerator)this).GenerateCodeFromType(c, _output.InnerWriter, _options);
}
}
/// <internalonly/>
bool ICodeGenerator.Supports(GeneratorSupport support)
{
return this.Supports(support);
}
/// <internalonly/>
void ICodeGenerator.GenerateCodeFromType(CodeTypeDeclaration e, TextWriter w, CodeGeneratorOptions o)
{
bool setLocal = false;
if (_output != null && w != _output.InnerWriter)
{
throw new InvalidOperationException(SRCodeDom.CodeGenOutputWriter);
}
if (_output == null)
{
setLocal = true;
_options = (o == null) ? new CodeGeneratorOptions() : o;
_output = new IndentedTextWriter(w, _options.IndentString);
}
try
{
GenerateType(e);
}
finally
{
if (setLocal)
{
_output = null;
_options = null;
}
}
}
/// <internalonly/>
void ICodeGenerator.GenerateCodeFromExpression(CodeExpression e, TextWriter w, CodeGeneratorOptions o)
{
bool setLocal = false;
if (_output != null && w != _output.InnerWriter)
{
throw new InvalidOperationException(SRCodeDom.CodeGenOutputWriter);
}
if (_output == null)
{
setLocal = true;
_options = (o == null) ? new CodeGeneratorOptions() : o;
_output = new IndentedTextWriter(w, _options.IndentString);
}
try
{
GenerateExpression(e);
}
finally
{
if (setLocal)
{
_output = null;
_options = null;
}
}
}
/// <internalonly/>
void ICodeGenerator.GenerateCodeFromCompileUnit(CodeCompileUnit e, TextWriter w, CodeGeneratorOptions o)
{
bool setLocal = false;
if (_output != null && w != _output.InnerWriter)
{
throw new InvalidOperationException(SRCodeDom.CodeGenOutputWriter);
}
if (_output == null)
{
setLocal = true;
_options = (o == null) ? new CodeGeneratorOptions() : o;
_output = new IndentedTextWriter(w, _options.IndentString);
}
try
{
if (e is CodeSnippetCompileUnit)
{
GenerateSnippetCompileUnit((CodeSnippetCompileUnit)e);
}
else
{
GenerateCompileUnit(e);
}
}
finally
{
if (setLocal)
{
_output = null;
_options = null;
}
}
}
/// <internalonly/>
void ICodeGenerator.GenerateCodeFromNamespace(CodeNamespace e, TextWriter w, CodeGeneratorOptions o)
{
bool setLocal = false;
if (_output != null && w != _output.InnerWriter)
{
throw new InvalidOperationException(SRCodeDom.CodeGenOutputWriter);
}
if (_output == null)
{
setLocal = true;
_options = (o == null) ? new CodeGeneratorOptions() : o;
_output = new IndentedTextWriter(w, _options.IndentString);
}
try
{
GenerateNamespace(e);
}
finally
{
if (setLocal)
{
_output = null;
_options = null;
}
}
}
/// <internalonly/>
void ICodeGenerator.GenerateCodeFromStatement(CodeStatement e, TextWriter w, CodeGeneratorOptions o)
{
bool setLocal = false;
if (_output != null && w != _output.InnerWriter)
{
throw new InvalidOperationException(SRCodeDom.CodeGenOutputWriter);
}
if (_output == null)
{
setLocal = true;
_options = (o == null) ? new CodeGeneratorOptions() : o;
_output = new IndentedTextWriter(w, _options.IndentString);
}
try
{
GenerateStatement(e);
}
finally
{
if (setLocal)
{
_output = null;
_options = null;
}
}
}
public virtual void GenerateCodeFromMember(CodeTypeMember member, TextWriter writer, CodeGeneratorOptions options)
{
if (_output != null)
{
throw new InvalidOperationException(SRCodeDom.CodeGenReentrance);
}
_options = (options == null) ? new CodeGeneratorOptions() : options;
_output = new IndentedTextWriter(writer, _options.IndentString);
try
{
CodeTypeDeclaration dummyClass = new CodeTypeDeclaration();
_currentClass = dummyClass;
GenerateTypeMember(member, dummyClass);
}
finally
{
_currentClass = null;
_output = null;
_options = null;
}
}
/// <internalonly/>
bool ICodeGenerator.IsValidIdentifier(string value)
{
return this.IsValidIdentifier(value);
}
/// <internalonly/>
void ICodeGenerator.ValidateIdentifier(string value)
{
this.ValidateIdentifier(value);
}
/// <internalonly/>
string ICodeGenerator.CreateEscapedIdentifier(string value)
{
return this.CreateEscapedIdentifier(value);
}
/// <internalonly/>
string ICodeGenerator.CreateValidIdentifier(string value)
{
return this.CreateValidIdentifier(value);
}
/// <internalonly/>
string ICodeGenerator.GetTypeOutput(CodeTypeReference type)
{
return this.GetTypeOutput(type);
}
private void GenerateConstructors(CodeTypeDeclaration e)
{
IEnumerator en = e.Members.GetEnumerator();
while (en.MoveNext())
{
if (en.Current is CodeConstructor)
{
_currentMember = (CodeTypeMember)en.Current;
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
if (_currentMember.StartDirectives.Count > 0)
{
GenerateDirectives(_currentMember.StartDirectives);
}
GenerateCommentStatements(_currentMember.Comments);
CodeConstructor imp = (CodeConstructor)en.Current;
if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma);
GenerateConstructor(imp, e);
if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma);
if (_currentMember.EndDirectives.Count > 0)
{
GenerateDirectives(_currentMember.EndDirectives);
}
}
}
}
private void GenerateEvents(CodeTypeDeclaration e)
{
IEnumerator en = e.Members.GetEnumerator();
while (en.MoveNext())
{
if (en.Current is CodeMemberEvent)
{
_currentMember = (CodeTypeMember)en.Current;
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
if (_currentMember.StartDirectives.Count > 0)
{
GenerateDirectives(_currentMember.StartDirectives);
}
GenerateCommentStatements(_currentMember.Comments);
CodeMemberEvent imp = (CodeMemberEvent)en.Current;
if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma);
GenerateEvent(imp, e);
if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma);
if (_currentMember.EndDirectives.Count > 0)
{
GenerateDirectives(_currentMember.EndDirectives);
}
}
}
}
/// <devdoc>
/// <para>Generates code for the specified CodeDom code expression representation.</para>
/// </devdoc>
protected void GenerateExpression(CodeExpression e)
{
if (e is CodeArrayCreateExpression)
{
GenerateArrayCreateExpression((CodeArrayCreateExpression)e);
}
else if (e is CodeBaseReferenceExpression)
{
GenerateBaseReferenceExpression((CodeBaseReferenceExpression)e);
}
else if (e is CodeBinaryOperatorExpression)
{
GenerateBinaryOperatorExpression((CodeBinaryOperatorExpression)e);
}
else if (e is CodeCastExpression)
{
GenerateCastExpression((CodeCastExpression)e);
}
else if (e is CodeDelegateCreateExpression)
{
GenerateDelegateCreateExpression((CodeDelegateCreateExpression)e);
}
else if (e is CodeFieldReferenceExpression)
{
GenerateFieldReferenceExpression((CodeFieldReferenceExpression)e);
}
else if (e is CodeArgumentReferenceExpression)
{
GenerateArgumentReferenceExpression((CodeArgumentReferenceExpression)e);
}
else if (e is CodeVariableReferenceExpression)
{
GenerateVariableReferenceExpression((CodeVariableReferenceExpression)e);
}
else if (e is CodeIndexerExpression)
{
GenerateIndexerExpression((CodeIndexerExpression)e);
}
else if (e is CodeArrayIndexerExpression)
{
GenerateArrayIndexerExpression((CodeArrayIndexerExpression)e);
}
else if (e is CodeSnippetExpression)
{
GenerateSnippetExpression((CodeSnippetExpression)e);
}
else if (e is CodeMethodInvokeExpression)
{
GenerateMethodInvokeExpression((CodeMethodInvokeExpression)e);
}
else if (e is CodeMethodReferenceExpression)
{
GenerateMethodReferenceExpression((CodeMethodReferenceExpression)e);
}
else if (e is CodeEventReferenceExpression)
{
GenerateEventReferenceExpression((CodeEventReferenceExpression)e);
}
else if (e is CodeDelegateInvokeExpression)
{
GenerateDelegateInvokeExpression((CodeDelegateInvokeExpression)e);
}
else if (e is CodeObjectCreateExpression)
{
GenerateObjectCreateExpression((CodeObjectCreateExpression)e);
}
else if (e is CodeParameterDeclarationExpression)
{
GenerateParameterDeclarationExpression((CodeParameterDeclarationExpression)e);
}
else if (e is CodeDirectionExpression)
{
GenerateDirectionExpression((CodeDirectionExpression)e);
}
else if (e is CodePrimitiveExpression)
{
GeneratePrimitiveExpression((CodePrimitiveExpression)e);
}
else if (e is CodePropertyReferenceExpression)
{
GeneratePropertyReferenceExpression((CodePropertyReferenceExpression)e);
}
else if (e is CodePropertySetValueReferenceExpression)
{
GeneratePropertySetValueReferenceExpression((CodePropertySetValueReferenceExpression)e);
}
else if (e is CodeThisReferenceExpression)
{
GenerateThisReferenceExpression((CodeThisReferenceExpression)e);
}
else if (e is CodeTypeReferenceExpression)
{
GenerateTypeReferenceExpression((CodeTypeReferenceExpression)e);
}
else if (e is CodeTypeOfExpression)
{
GenerateTypeOfExpression((CodeTypeOfExpression)e);
}
else if (e is CodeDefaultValueExpression)
{
GenerateDefaultValueExpression((CodeDefaultValueExpression)e);
}
else
{
if (e == null)
{
throw new ArgumentNullException("e");
}
else
{
throw new ArgumentException(string.Format(SRCodeDom.InvalidElementType, e.GetType().FullName), "e");
}
}
}
private void GenerateFields(CodeTypeDeclaration e)
{
IEnumerator en = e.Members.GetEnumerator();
while (en.MoveNext())
{
if (en.Current is CodeMemberField)
{
_currentMember = (CodeTypeMember)en.Current;
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
if (_currentMember.StartDirectives.Count > 0)
{
GenerateDirectives(_currentMember.StartDirectives);
}
GenerateCommentStatements(_currentMember.Comments);
CodeMemberField imp = (CodeMemberField)en.Current;
if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma);
GenerateField(imp);
if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma);
if (_currentMember.EndDirectives.Count > 0)
{
GenerateDirectives(_currentMember.EndDirectives);
}
}
}
}
private void GenerateSnippetMembers(CodeTypeDeclaration e)
{
IEnumerator en = e.Members.GetEnumerator();
bool hasSnippet = false;
while (en.MoveNext())
{
if (en.Current is CodeSnippetTypeMember)
{
hasSnippet = true;
_currentMember = (CodeTypeMember)en.Current;
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
if (_currentMember.StartDirectives.Count > 0)
{
GenerateDirectives(_currentMember.StartDirectives);
}
GenerateCommentStatements(_currentMember.Comments);
CodeSnippetTypeMember imp = (CodeSnippetTypeMember)en.Current;
if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma);
// Don't indent snippets, in order to preserve the column
// information from the original code. This improves the debugging
// experience.
int savedIndent = Indent;
Indent = 0;
GenerateSnippetMember(imp);
// Restore the indent
Indent = savedIndent;
if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma);
if (_currentMember.EndDirectives.Count > 0)
{
GenerateDirectives(_currentMember.EndDirectives);
}
}
}
// Generate an extra new line at the end of the snippet.
// If the snippet is comment and this type only contains comments.
// The generated code will not compile.
if (hasSnippet)
{
Output.WriteLine();
}
}
/// <devdoc>
/// <para> Generates code for the specified snippet code block
/// </para>
/// </devdoc>
protected virtual void GenerateSnippetCompileUnit(CodeSnippetCompileUnit e)
{
GenerateDirectives(e.StartDirectives);
if (e.LinePragma != null) GenerateLinePragmaStart(e.LinePragma);
Output.WriteLine(e.Value);
if (e.LinePragma != null) GenerateLinePragmaEnd(e.LinePragma);
if (e.EndDirectives.Count > 0)
{
GenerateDirectives(e.EndDirectives);
}
}
private void GenerateMethods(CodeTypeDeclaration e)
{
IEnumerator en = e.Members.GetEnumerator();
while (en.MoveNext())
{
if (en.Current is CodeMemberMethod
&& !(en.Current is CodeTypeConstructor)
&& !(en.Current is CodeConstructor))
{
_currentMember = (CodeTypeMember)en.Current;
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
if (_currentMember.StartDirectives.Count > 0)
{
GenerateDirectives(_currentMember.StartDirectives);
}
GenerateCommentStatements(_currentMember.Comments);
CodeMemberMethod imp = (CodeMemberMethod)en.Current;
if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma);
if (en.Current is CodeEntryPointMethod)
{
GenerateEntryPointMethod((CodeEntryPointMethod)en.Current, e);
}
else
{
GenerateMethod(imp, e);
}
if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma);
if (_currentMember.EndDirectives.Count > 0)
{
GenerateDirectives(_currentMember.EndDirectives);
}
}
}
}
private void GenerateNestedTypes(CodeTypeDeclaration e)
{
IEnumerator en = e.Members.GetEnumerator();
while (en.MoveNext())
{
if (en.Current is CodeTypeDeclaration)
{
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
CodeTypeDeclaration currentClass = (CodeTypeDeclaration)en.Current;
((ICodeGenerator)this).GenerateCodeFromType(currentClass, _output.InnerWriter, _options);
}
}
}
/// <devdoc>
/// <para> Generates code for the specified CodeDom
/// compile unit representation.</para>
/// </devdoc>
protected virtual void GenerateCompileUnit(CodeCompileUnit e)
{
GenerateCompileUnitStart(e);
GenerateNamespaces(e);
GenerateCompileUnitEnd(e);
}
/// <devdoc>
/// <para> Generates code for the specified CodeDom
/// namespace representation.</para>
/// </devdoc>
protected virtual void GenerateNamespace(CodeNamespace e)
{
GenerateCommentStatements(e.Comments);
GenerateNamespaceStart(e);
GenerateNamespaceImports(e);
Output.WriteLine("");
GenerateTypes(e);
GenerateNamespaceEnd(e);
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based namespace import
/// representation.
/// </para>
/// </devdoc>
protected void GenerateNamespaceImports(CodeNamespace e)
{
IEnumerator en = e.Imports.GetEnumerator();
while (en.MoveNext())
{
CodeNamespaceImport imp = (CodeNamespaceImport)en.Current;
if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma);
GenerateNamespaceImport(imp);
if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma);
}
}
private void GenerateProperties(CodeTypeDeclaration e)
{
IEnumerator en = e.Members.GetEnumerator();
while (en.MoveNext())
{
if (en.Current is CodeMemberProperty)
{
_currentMember = (CodeTypeMember)en.Current;
if (_options.BlankLinesBetweenMembers)
{
Output.WriteLine();
}
if (_currentMember.StartDirectives.Count > 0)
{
GenerateDirectives(_currentMember.StartDirectives);
}
GenerateCommentStatements(_currentMember.Comments);
CodeMemberProperty imp = (CodeMemberProperty)en.Current;
if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma);
GenerateProperty(imp, e);
if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma);
if (_currentMember.EndDirectives.Count > 0)
{
GenerateDirectives(_currentMember.EndDirectives);
}
}
}
}
/// <devdoc>
/// <para>
/// Generates code for
/// the specified CodeDom based statement representation.
/// </para>
/// </devdoc>
protected void GenerateStatement(CodeStatement e)
{
if (e.StartDirectives.Count > 0)
{
GenerateDirectives(e.StartDirectives);
}
if (e.LinePragma != null)
{
GenerateLinePragmaStart(e.LinePragma);
}
if (e is CodeCommentStatement)
{
GenerateCommentStatement((CodeCommentStatement)e);
}
else if (e is CodeMethodReturnStatement)
{
GenerateMethodReturnStatement((CodeMethodReturnStatement)e);
}
else if (e is CodeConditionStatement)
{
GenerateConditionStatement((CodeConditionStatement)e);
}
else if (e is CodeTryCatchFinallyStatement)
{
GenerateTryCatchFinallyStatement((CodeTryCatchFinallyStatement)e);
}
else if (e is CodeAssignStatement)
{
GenerateAssignStatement((CodeAssignStatement)e);
}
else if (e is CodeExpressionStatement)
{
GenerateExpressionStatement((CodeExpressionStatement)e);
}
else if (e is CodeIterationStatement)
{
GenerateIterationStatement((CodeIterationStatement)e);
}
else if (e is CodeThrowExceptionStatement)
{
GenerateThrowExceptionStatement((CodeThrowExceptionStatement)e);
}
else if (e is CodeSnippetStatement)
{
// Don't indent snippet statements, in order to preserve the column
// information from the original code. This improves the debugging
// experience.
int savedIndent = Indent;
Indent = 0;
GenerateSnippetStatement((CodeSnippetStatement)e);
// Restore the indent
Indent = savedIndent;
}
else if (e is CodeVariableDeclarationStatement)
{
GenerateVariableDeclarationStatement((CodeVariableDeclarationStatement)e);
}
else if (e is CodeAttachEventStatement)
{
GenerateAttachEventStatement((CodeAttachEventStatement)e);
}
else if (e is CodeRemoveEventStatement)
{
GenerateRemoveEventStatement((CodeRemoveEventStatement)e);
}
else if (e is CodeGotoStatement)
{
GenerateGotoStatement((CodeGotoStatement)e);
}
else if (e is CodeLabeledStatement)
{
GenerateLabeledStatement((CodeLabeledStatement)e);
}
else
{
throw new ArgumentException(string.Format(SRCodeDom.InvalidElementType, e.GetType().FullName), "e");
}
if (e.LinePragma != null)
{
GenerateLinePragmaEnd(e.LinePragma);
}
if (e.EndDirectives.Count > 0)
{
GenerateDirectives(e.EndDirectives);
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based statement representations.
/// </para>
/// </devdoc>
protected void GenerateStatements(CodeStatementCollection stms)
{
IEnumerator en = stms.GetEnumerator();
while (en.MoveNext())
{
((ICodeGenerator)this).GenerateCodeFromStatement((CodeStatement)en.Current, _output.InnerWriter, _options);
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified Microsoft.CodeDom.CodeAttributeBlock.
/// </para>
/// </devdoc>
protected virtual void OutputAttributeDeclarations(CodeAttributeDeclarationCollection attributes)
{
if (attributes.Count == 0) return;
GenerateAttributeDeclarationsStart(attributes);
bool first = true;
IEnumerator en = attributes.GetEnumerator();
while (en.MoveNext())
{
if (first)
{
first = false;
}
else
{
ContinueOnNewLine(", ");
}
CodeAttributeDeclaration current = (CodeAttributeDeclaration)en.Current;
Output.Write(current.Name);
Output.Write("(");
bool firstArg = true;
foreach (CodeAttributeArgument arg in current.Arguments)
{
if (firstArg)
{
firstArg = false;
}
else
{
Output.Write(", ");
}
OutputAttributeArgument(arg);
}
Output.Write(")");
}
GenerateAttributeDeclarationsEnd(attributes);
}
/// <devdoc>
/// <para>
/// Outputs an argument in a attribute block.
/// </para>
/// </devdoc>
protected virtual void OutputAttributeArgument(CodeAttributeArgument arg)
{
if (arg.Name != null && arg.Name.Length > 0)
{
OutputIdentifier(arg.Name);
Output.Write("=");
}
((ICodeGenerator)this).GenerateCodeFromExpression(arg.Value, _output.InnerWriter, _options);
}
/// <devdoc>
/// <para>
/// Generates code for the specified Microsoft.CodeDom.FieldDirection.
/// </para>
/// </devdoc>
protected virtual void OutputDirection(FieldDirection dir)
{
switch (dir)
{
case FieldDirection.In:
break;
case FieldDirection.Out:
Output.Write("out ");
break;
case FieldDirection.Ref:
Output.Write("ref ");
break;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void OutputFieldScopeModifier(MemberAttributes attributes)
{
switch (attributes & MemberAttributes.VTableMask)
{
case MemberAttributes.New:
Output.Write("new ");
break;
}
switch (attributes & MemberAttributes.ScopeMask)
{
case MemberAttributes.Final:
break;
case MemberAttributes.Static:
Output.Write("static ");
break;
case MemberAttributes.Const:
Output.Write("const ");
break;
default:
break;
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified member access modifier.
/// </para>
/// </devdoc>
protected virtual void OutputMemberAccessModifier(MemberAttributes attributes)
{
switch (attributes & MemberAttributes.AccessMask)
{
case MemberAttributes.Assembly:
Output.Write("internal ");
break;
case MemberAttributes.FamilyAndAssembly:
Output.Write("internal "); /*FamANDAssem*/
break;
case MemberAttributes.Family:
Output.Write("protected ");
break;
case MemberAttributes.FamilyOrAssembly:
Output.Write("protected internal ");
break;
case MemberAttributes.Private:
Output.Write("private ");
break;
case MemberAttributes.Public:
Output.Write("public ");
break;
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified member scope modifier.
/// </para>
/// </devdoc>
protected virtual void OutputMemberScopeModifier(MemberAttributes attributes)
{
switch (attributes & MemberAttributes.VTableMask)
{
case MemberAttributes.New:
Output.Write("new ");
break;
}
switch (attributes & MemberAttributes.ScopeMask)
{
case MemberAttributes.Abstract:
Output.Write("abstract ");
break;
case MemberAttributes.Final:
Output.Write("");
break;
case MemberAttributes.Static:
Output.Write("static ");
break;
case MemberAttributes.Override:
Output.Write("override ");
break;
default:
switch (attributes & MemberAttributes.AccessMask)
{
case MemberAttributes.Family:
case MemberAttributes.Public:
Output.Write("virtual ");
break;
default:
// nothing;
break;
}
break;
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified type.
/// </para>
/// </devdoc>
protected abstract void OutputType(CodeTypeReference typeRef);
/// <devdoc>
/// <para>
/// Generates code for the specified type attributes.
/// </para>
/// </devdoc>
protected virtual void OutputTypeAttributes(TypeAttributes attributes, bool isStruct, bool isEnum)
{
switch (attributes & TypeAttributes.VisibilityMask)
{
case TypeAttributes.Public:
case TypeAttributes.NestedPublic:
Output.Write("public ");
break;
case TypeAttributes.NestedPrivate:
Output.Write("private ");
break;
}
if (isStruct)
{
Output.Write("struct ");
}
else if (isEnum)
{
Output.Write("enum ");
}
else
{
switch (attributes & TypeAttributes.ClassSemanticsMask)
{
case TypeAttributes.Class:
if ((attributes & TypeAttributes.Sealed) == TypeAttributes.Sealed)
{
Output.Write("sealed ");
}
if ((attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract)
{
Output.Write("abstract ");
}
Output.Write("class ");
break;
case TypeAttributes.Interface:
Output.Write("interface ");
break;
}
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified object type and name pair.
/// </para>
/// </devdoc>
protected virtual void OutputTypeNamePair(CodeTypeReference typeRef, string name)
{
OutputType(typeRef);
Output.Write(" ");
OutputIdentifier(name);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void OutputIdentifier(string ident)
{
Output.Write(ident);
}
/// <devdoc>
/// <para>
/// Generates code for the specified expression list.
/// </para>
/// </devdoc>
protected virtual void OutputExpressionList(CodeExpressionCollection expressions)
{
OutputExpressionList(expressions, false /*newlineBetweenItems*/);
}
/// <devdoc>
/// <para>
/// Generates code for the specified expression list.
/// </para>
/// </devdoc>
protected virtual void OutputExpressionList(CodeExpressionCollection expressions, bool newlineBetweenItems)
{
bool first = true;
IEnumerator en = expressions.GetEnumerator();
Indent++;
while (en.MoveNext())
{
if (first)
{
first = false;
}
else
{
if (newlineBetweenItems)
ContinueOnNewLine(",");
else
Output.Write(", ");
}
((ICodeGenerator)this).GenerateCodeFromExpression((CodeExpression)en.Current, _output.InnerWriter, _options);
}
Indent--;
}
/// <devdoc>
/// <para>
/// Generates code for the specified operator.
/// </para>
/// </devdoc>
protected virtual void OutputOperator(CodeBinaryOperatorType op)
{
switch (op)
{
case CodeBinaryOperatorType.Add:
Output.Write("+");
break;
case CodeBinaryOperatorType.Subtract:
Output.Write("-");
break;
case CodeBinaryOperatorType.Multiply:
Output.Write("*");
break;
case CodeBinaryOperatorType.Divide:
Output.Write("/");
break;
case CodeBinaryOperatorType.Modulus:
Output.Write("%");
break;
case CodeBinaryOperatorType.Assign:
Output.Write("=");
break;
case CodeBinaryOperatorType.IdentityInequality:
Output.Write("!=");
break;
case CodeBinaryOperatorType.IdentityEquality:
Output.Write("==");
break;
case CodeBinaryOperatorType.ValueEquality:
Output.Write("==");
break;
case CodeBinaryOperatorType.BitwiseOr:
Output.Write("|");
break;
case CodeBinaryOperatorType.BitwiseAnd:
Output.Write("&");
break;
case CodeBinaryOperatorType.BooleanOr:
Output.Write("||");
break;
case CodeBinaryOperatorType.BooleanAnd:
Output.Write("&&");
break;
case CodeBinaryOperatorType.LessThan:
Output.Write("<");
break;
case CodeBinaryOperatorType.LessThanOrEqual:
Output.Write("<=");
break;
case CodeBinaryOperatorType.GreaterThan:
Output.Write(">");
break;
case CodeBinaryOperatorType.GreaterThanOrEqual:
Output.Write(">=");
break;
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified parameters.
/// </para>
/// </devdoc>
protected virtual void OutputParameters(CodeParameterDeclarationExpressionCollection parameters)
{
bool first = true;
bool multiline = parameters.Count > ParameterMultilineThreshold;
if (multiline)
{
Indent += 3;
}
IEnumerator en = parameters.GetEnumerator();
while (en.MoveNext())
{
CodeParameterDeclarationExpression current = (CodeParameterDeclarationExpression)en.Current;
if (first)
{
first = false;
}
else
{
Output.Write(", ");
}
if (multiline)
{
ContinueOnNewLine("");
}
GenerateExpression(current);
}
if (multiline)
{
Indent -= 3;
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based array creation expression
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateArrayCreateExpression(CodeArrayCreateExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based base reference expression
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateBaseReferenceExpression(CodeBaseReferenceExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based binary operator
/// expression representation.
/// </para>
/// </devdoc>
protected virtual void GenerateBinaryOperatorExpression(CodeBinaryOperatorExpression e)
{
bool indentedExpression = false;
Output.Write("(");
GenerateExpression(e.Left);
Output.Write(" ");
if (e.Left is CodeBinaryOperatorExpression || e.Right is CodeBinaryOperatorExpression)
{
// In case the line gets too long with nested binary operators, we need to output them on
// different lines. However we want to indent them to maintain readability, but this needs
// to be done only once;
if (!_inNestedBinary)
{
indentedExpression = true;
_inNestedBinary = true;
Indent += 3;
}
ContinueOnNewLine("");
}
OutputOperator(e.Operator);
Output.Write(" ");
GenerateExpression(e.Right);
Output.Write(")");
if (indentedExpression)
{
Indent -= 3;
_inNestedBinary = false;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void ContinueOnNewLine(string st)
{
Output.WriteLine(st);
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based cast expression
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateCastExpression(CodeCastExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based delegate creation expression
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateDelegateCreateExpression(CodeDelegateCreateExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based field reference
/// expression representation.
/// </para>
/// </devdoc>
protected abstract void GenerateFieldReferenceExpression(CodeFieldReferenceExpression e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateArgumentReferenceExpression(CodeArgumentReferenceExpression e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateVariableReferenceExpression(CodeVariableReferenceExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based indexer expression
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateIndexerExpression(CodeIndexerExpression e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateArrayIndexerExpression(CodeArrayIndexerExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based snippet
/// expression representation.
/// </para>
/// </devdoc>
protected abstract void GenerateSnippetExpression(CodeSnippetExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based method invoke expression
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateMethodInvokeExpression(CodeMethodInvokeExpression e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateMethodReferenceExpression(CodeMethodReferenceExpression e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateEventReferenceExpression(CodeEventReferenceExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based delegate invoke expression
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateDelegateInvokeExpression(CodeDelegateInvokeExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom
/// based object creation expression representation.
/// </para>
/// </devdoc>
protected abstract void GenerateObjectCreateExpression(CodeObjectCreateExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom
/// based parameter declaration expression representation.
/// </para>
/// </devdoc>
protected virtual void GenerateParameterDeclarationExpression(CodeParameterDeclarationExpression e)
{
if (e.CustomAttributes.Count > 0)
{
OutputAttributeDeclarations(e.CustomAttributes);
Output.Write(" ");
}
OutputDirection(e.Direction);
OutputTypeNamePair(e.Type, e.Name);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void GenerateDirectionExpression(CodeDirectionExpression e)
{
OutputDirection(e.Direction);
GenerateExpression(e.Expression);
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based primitive expression
/// representation.
/// </para>
/// </devdoc>
protected virtual void GeneratePrimitiveExpression(CodePrimitiveExpression e)
{
if (e.Value == null)
{
Output.Write(NullToken);
}
else if (e.Value is string)
{
Output.Write(QuoteSnippetString((string)e.Value));
}
else if (e.Value is char)
{
Output.Write("'" + e.Value.ToString() + "'");
}
else if (e.Value is byte)
{
Output.Write(((byte)e.Value).ToString());
}
else if (e.Value is Int16)
{
Output.Write(((Int16)e.Value).ToString());
}
else if (e.Value is Int32)
{
Output.Write(((Int32)e.Value).ToString());
}
else if (e.Value is Int64)
{
Output.Write(((Int64)e.Value).ToString());
}
else if (e.Value is Single)
{
GenerateSingleFloatValue((Single)e.Value);
}
else if (e.Value is Double)
{
GenerateDoubleValue((Double)e.Value);
}
else if (e.Value is Decimal)
{
GenerateDecimalValue((Decimal)e.Value);
}
else if (e.Value is bool)
{
if ((bool)e.Value)
{
Output.Write("true");
}
else
{
Output.Write("false");
}
}
else
{
throw new ArgumentException(string.Format(SRCodeDom.InvalidPrimitiveType, e.Value.GetType().ToString()));
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void GenerateSingleFloatValue(Single s)
{
Output.Write(s.ToString("R", CultureInfo.InvariantCulture));
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void GenerateDoubleValue(Double d)
{
Output.Write(d.ToString("R", CultureInfo.InvariantCulture));
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void GenerateDecimalValue(Decimal d)
{
Output.Write(d.ToString());
}
// TODO: this should be abstract, but that will break language providers which don't support DefaultValueExpression.
protected virtual void GenerateDefaultValueExpression(CodeDefaultValueExpression e)
{
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based property reference
/// expression representation.
/// </para>
/// </devdoc>
protected abstract void GeneratePropertyReferenceExpression(CodePropertyReferenceExpression e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GeneratePropertySetValueReferenceExpression(CodePropertySetValueReferenceExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based this reference expression
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateThisReferenceExpression(CodeThisReferenceExpression e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based type reference expression
/// representation.
/// </para>
/// </devdoc>
protected virtual void GenerateTypeReferenceExpression(CodeTypeReferenceExpression e)
{
OutputType(e.Type);
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based type of expression
/// representation.
/// </para>
/// </devdoc>
protected virtual void GenerateTypeOfExpression(CodeTypeOfExpression e)
{
Output.Write("typeof(");
OutputType(e.Type);
Output.Write(")");
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based method
/// invoke statement representation.
/// </para>
/// </devdoc>
protected abstract void GenerateExpressionStatement(CodeExpressionStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based for loop statement
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateIterationStatement(CodeIterationStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based throw exception statement
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateThrowExceptionStatement(CodeThrowExceptionStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based comment statement
/// representation.
/// </para>
/// </devdoc>
protected virtual void GenerateCommentStatement(CodeCommentStatement e)
{
if (e.Comment == null)
throw new ArgumentException(string.Format(SRCodeDom.Argument_NullComment, "e"), "e");
GenerateComment(e.Comment);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void GenerateCommentStatements(CodeCommentStatementCollection e)
{
foreach (CodeCommentStatement comment in e)
{
GenerateCommentStatement(comment);
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateComment(CodeComment e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based method return statement
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateMethodReturnStatement(CodeMethodReturnStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based if statement representation.
/// </para>
/// </devdoc>
protected abstract void GenerateConditionStatement(CodeConditionStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based try catch finally
/// statement representation.
/// </para>
/// </devdoc>
protected abstract void GenerateTryCatchFinallyStatement(CodeTryCatchFinallyStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based assignment statement
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateAssignStatement(CodeAssignStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based attach event statement
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateAttachEventStatement(CodeAttachEventStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based detach event statement
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateRemoveEventStatement(CodeRemoveEventStatement e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateGotoStatement(CodeGotoStatement e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateLabeledStatement(CodeLabeledStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based snippet statement
/// representation.
/// </para>
/// </devdoc>
protected virtual void GenerateSnippetStatement(CodeSnippetStatement e)
{
Output.WriteLine(e.Value);
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based variable declaration statement
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateVariableDeclarationStatement(CodeVariableDeclarationStatement e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based line pragma start
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateLinePragmaStart(CodeLinePragma e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based line pragma end
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateLinePragmaEnd(CodeLinePragma e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based event
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateEvent(CodeMemberEvent e, CodeTypeDeclaration c);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based member field
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateField(CodeMemberField e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based snippet class member
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateSnippetMember(CodeSnippetTypeMember e);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract void GenerateEntryPointMethod(CodeEntryPointMethod e, CodeTypeDeclaration c);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based method
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateMethod(CodeMemberMethod e, CodeTypeDeclaration c);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based property
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateProperty(CodeMemberProperty e, CodeTypeDeclaration c);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based constructor
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateConstructor(CodeConstructor e, CodeTypeDeclaration c);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based class constructor
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateTypeConstructor(CodeTypeConstructor e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based start class representation.
/// </para>
/// </devdoc>
protected abstract void GenerateTypeStart(CodeTypeDeclaration e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based end class representation.
/// </para>
/// </devdoc>
protected abstract void GenerateTypeEnd(CodeTypeDeclaration e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based compile unit start
/// representation.
/// </para>
/// </devdoc>
protected virtual void GenerateCompileUnitStart(CodeCompileUnit e)
{
if (e.StartDirectives.Count > 0)
{
GenerateDirectives(e.StartDirectives);
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based compile unit end
/// representation.
/// </para>
/// </devdoc>
protected virtual void GenerateCompileUnitEnd(CodeCompileUnit e)
{
if (e.EndDirectives.Count > 0)
{
GenerateDirectives(e.EndDirectives);
}
}
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based namespace start
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateNamespaceStart(CodeNamespace e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based namespace end
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateNamespaceEnd(CodeNamespace e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based namespace import
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateNamespaceImport(CodeNamespaceImport e);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based attribute block start
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateAttributeDeclarationsStart(CodeAttributeDeclarationCollection attributes);
/// <devdoc>
/// <para>
/// Generates code for the specified CodeDom based attribute block end
/// representation.
/// </para>
/// </devdoc>
protected abstract void GenerateAttributeDeclarationsEnd(CodeAttributeDeclarationCollection attributes);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract bool Supports(GeneratorSupport support);
/// <devdoc>
/// <para>
/// Gets or sets whether the specified value is a value identifier.
/// </para>
/// </devdoc>
protected abstract bool IsValidIdentifier(string value);
/// <devdoc>
/// <para>
/// Gets whether the specified identifier is valid.
/// </para>
/// </devdoc>
protected virtual void ValidateIdentifier(string value)
{
if (!IsValidIdentifier(value))
{
throw new ArgumentException(string.Format(SRCodeDom.InvalidIdentifier, value));
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract string CreateEscapedIdentifier(string value);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract string CreateValidIdentifier(string value);
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected abstract string GetTypeOutput(CodeTypeReference value);
/// <devdoc>
/// <para>
/// Provides conversion to formatting with escape codes.
/// </para>
/// </devdoc>
protected abstract string QuoteSnippetString(string value);
/// <devdoc>
/// <para>
/// Gets a value indicating whether the specified value is a valid language
/// independent identifier.
/// </para>
/// </devdoc>
public static bool IsValidLanguageIndependentIdentifier(string value)
{
return IsValidTypeNameOrIdentifier(value, false);
}
internal static bool IsValidLanguageIndependentTypeName(string value)
{
return IsValidTypeNameOrIdentifier(value, true);
}
private static bool IsValidTypeNameOrIdentifier(string value, bool isTypeName)
{
bool nextMustBeStartChar = true;
if (value.Length == 0)
return false;
// each char must be Lu, Ll, Lt, Lm, Lo, Nd, Mn, Mc, Pc
//
for (int i = 0; i < value.Length; i++)
{
char ch = value[i];
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(ch);
switch (uc)
{
case UnicodeCategory.UppercaseLetter: // Lu
case UnicodeCategory.LowercaseLetter: // Ll
case UnicodeCategory.TitlecaseLetter: // Lt
case UnicodeCategory.ModifierLetter: // Lm
case UnicodeCategory.LetterNumber: // Lm
case UnicodeCategory.OtherLetter: // Lo
nextMustBeStartChar = false;
break;
case UnicodeCategory.NonSpacingMark: // Mn
case UnicodeCategory.SpacingCombiningMark: // Mc
case UnicodeCategory.ConnectorPunctuation: // Pc
case UnicodeCategory.DecimalDigitNumber: // Nd
// Underscore is a valid starting character, even though it is a ConnectorPunctuation.
if (nextMustBeStartChar && ch != '_')
return false;
nextMustBeStartChar = false;
break;
default:
// We only check the special Type chars for type names.
if (isTypeName && IsSpecialTypeChar(ch, ref nextMustBeStartChar))
{
break;
}
return false;
}
}
return true;
}
// This can be a special character like a separator that shows up in a type name
// This is an odd set of characters. Some come from characters that are allowed by C++, like < and >.
// Others are characters that are specified in the type and assembly name grammer.
private static bool IsSpecialTypeChar(char ch, ref bool nextMustBeStartChar)
{
switch (ch)
{
case ':':
case '.':
case '$':
case '+':
case '<':
case '>':
case '-':
case '[':
case ']':
case ',':
case '&':
case '*':
nextMustBeStartChar = true;
return true;
case '`':
return true;
}
return false;
}
/// <devdoc>
/// <para>
/// Validates a tree to check if all the types and idenfier names follow the rules of an identifier
/// in a langauge independent manner.
/// </para>
/// </devdoc>
public static void ValidateIdentifiers(CodeObject e)
{
CodeValidator codeValidator = new CodeValidator(); // This has internal state and hence is not static
codeValidator.ValidateIdentifiers(e);
}
}
}
|