static void _Patch(CodeMemberMethod meth, CodeDomVisitContext ctx, CodeDomResolver resolver) { if (null != meth) { // TODO: Populate public implementation types meth.UserData.Remove("slang:unresolved"); if ("Main" == meth.Name && (meth.Attributes & MemberAttributes.ScopeMask) == MemberAttributes.Static) { if (0 == meth.Parameters.Count && null == meth.ReturnType || "System.Void" == meth.ReturnType.BaseType) { var epm = new CodeEntryPointMethod(); epm.Attributes = meth.Attributes; epm.LinePragma = meth.LinePragma; epm.StartDirectives.AddRange(meth.StartDirectives); epm.EndDirectives.AddRange(meth.EndDirectives); epm.Comments.AddRange(meth.Comments); epm.CustomAttributes.AddRange(meth.CustomAttributes); epm.ReturnTypeCustomAttributes.AddRange(meth.ReturnTypeCustomAttributes); epm.TypeParameters.AddRange(meth.TypeParameters); epm.PrivateImplementationType = meth.PrivateImplementationType; epm.ImplementationTypes.AddRange(meth.ImplementationTypes); epm.Name = meth.Name; epm.Statements.AddRange(meth.Statements); CodeDomVisitor.ReplaceTarget(ctx, epm); } } //return; } }
/// <summary> /// Gets the next element that has not been resolved /// </summary> /// <param name="compileUnits">The compile units to search</param> /// <returns>A <see cref="CodeObject"/> representing the next code object that needs to be patched</returns> public static CodeObject GetNextUnresolvedElement(IEnumerable <CodeCompileUnit> compileUnits) { CodeObject result = null; foreach (var cu in compileUnits) { CodeDomVisitor.Visit(cu, (ctx) => { var co = ctx.Target as CodeObject; if (null != co) { if (co.UserData.Contains("slang:unresolved")) { result = co; ctx.Cancel = true; } } }); if (null != result) { return(result); } } return(null); }
static void _Patch(CodeDelegateInvokeExpression di, CodeDomVisitContext ctx, CodeDomResolver resolver) { if (null != di) { // these can be method invokes depending. if (null != di.TargetObject) { // probably already fixed in an earlier visit var mr = di.TargetObject as CodeMethodReferenceExpression; if (null != mr) { var mi = new CodeMethodInvokeExpression(mr); mi.Parameters.AddRange(di.Parameters); CodeDomVisitor.ReplaceTarget(ctx, mi); //args.Cancel = true; } else { var cco = di.TargetObject as CodeObject; if (null == cco) { System.Diagnostics.Debugger.Break(); } } } else { // we really are at a loss here as the only way this would be valid is // through a self call on a delegate object itself, like this(); throw new InvalidProgramException(_AppendLineInfo("Untargeted delegate invoke produced by slang parser", di)); } //return; } }
static void Demo4(CodeCompileUnit ccu) { // create one of these lil guys var res = new CodeDomResolver(); // add our code to it res.CompileUnits.Add(ccu); // give it a chance to build its information over our code res.Refresh(); CodeDomVisitor.Visit(ccu, (ctx) => { // for every expression... var expr = ctx.Target as CodeExpression; if (null != expr) { // except method reference expressions... var mri = expr as CodeMethodReferenceExpression; if (null != mri) { return; } // get the expression type var type = res.TryGetTypeOfExpression(expr); // write it along with the expression itself Console.WriteLine( "Expression type {0}: {1} is {2}", expr.GetType().Name, CodeDomUtility.ToString(expr), null != type?CodeDomUtility.ToString(type):"unresolvable"); } }); Console.WriteLine("Press any key..."); Console.ReadKey(); Console.Clear(); }
static void _Patch(CodeAssignStatement ast, CodeDomVisitContext ctx, CodeDomResolver res) { if (null != ast) { var eventRef = ast.Left as CodeEventReferenceExpression; if (null != eventRef) { var bo = ast.Right as CodeBinaryOperatorExpression; if (null != bo) { var trg = bo.Right; if (CodeBinaryOperatorType.Add == bo.Operator) { CodeDomVisitor.ReplaceTarget(ctx, new CodeAttachEventStatement(eventRef, trg)); } else if (CodeBinaryOperatorType.Subtract == bo.Operator) { CodeDomVisitor.ReplaceTarget(ctx, new CodeRemoveEventStatement(eventRef, trg)); } } } else if (!ast.Left.UserData.Contains("slang:unresolved")) { ast.UserData.Remove("slang:unresolved"); } } }
// The .Designer partial file produced by Visual Studio and SharpDevelop // does not specify the inherited type. The type is specified in the // non-designer generated file.E.g: // // partial Form1 - in Form1.Designer.cs // partial Form1 : Form - in Form1.cs // private CodeCompileUnit MergeParse(string fileName, string codeBehindFileName) { CodeCompileUnit mergedUnit = null; // parse codebehind IParser codeBehindParser = ICSharpCode.NRefactory.ParserFactory.CreateParser(codeBehindFileName); codeBehindParser.Parse(); // get the first valid typedeclaration name CodeDomVisitor visitor = new CodeDomVisitor(); // NRefactory can't decide on its own whether to generate CodePropertyReference or // CodeFieldReference. This will be done by the supplied by us IEnvironmentInformationProvider. // Our EnvironmentInformationProvider makes use of the ITypeResolutionService to get the type // (from the name) and check if a field is available. // visitor.EnvironmentInformationProvider = _informationProvider; visitor.VisitCompilationUnit(codeBehindParser.CompilationUnit, null); mergedUnit = visitor.codeCompileUnit; string codeBehindNamespaceName = null; CodeTypeDeclaration codeBehindType = GetFirstValidType(visitor.codeCompileUnit, out codeBehindNamespaceName); if (codeBehindType == null) { throw new InvalidOperationException("No class with an InitializeComponent method found"); } // parse file without the method bodies IParser fileParser = ICSharpCode.NRefactory.ParserFactory.CreateParser(fileName); fileParser.ParseMethodBodies = false; fileParser.Parse(); // match declaration name from codebehind and get the type visitor = new CodeDomVisitor(); visitor.VisitCompilationUnit(fileParser.CompilationUnit, null); foreach (CodeNamespace namesp in visitor.codeCompileUnit.Namespaces) { if (namesp.Name == codeBehindNamespaceName) { foreach (CodeTypeDeclaration declaration in namesp.Types) { if (declaration.Name == codeBehindType.Name) { foreach (CodeTypeReference baseType in declaration.BaseTypes) { codeBehindType.BaseTypes.Add(baseType); } } } } } fileParser.Dispose(); codeBehindParser.Dispose(); return(mergedUnit); }
public TemplateMemberGenerator(CodeGenerationContext context) { Context = context; if (!String.IsNullOrEmpty(context.Model.MemberTemplateFile)) { string templateFile = context.Model.MemberTemplateFile; if (!Path.IsPathRooted(templateFile)) { templateFile = Helper.FindFile(context.ModelFilePath, templateFile); } if (templateFile == null || !File.Exists(templateFile)) { throw new FileNotFoundException("Template file not found", context.Model.MemberTemplateFile); } SupportedLanguage language; if (templateFile.EndsWith(".cs", StringComparison.InvariantCultureIgnoreCase)) { language = SupportedLanguage.CSharp; } else if (templateFile.EndsWith(".vb", StringComparison.InvariantCultureIgnoreCase)) { language = SupportedLanguage.VBNet; } else { throw new Exception("Only .cs and .vb files are supported for MemberTemplateFile."); } using (StreamReader reader = new StreamReader(templateFile)) { IParser parser = ParserFactory.CreateParser(language, reader); parser.Parse(); if (parser.Errors.Count > 0) { throw new Exception("Error detected parsing MemberTemplateFile."); } CodeDomVisitor visit = new CodeDomVisitor(); visit.VisitCompilationUnit(parser.CompilationUnit, null); // Remove Unsed Namespaces for (int i = visit.codeCompileUnit.Namespaces.Count - 1; i >= 0; i--) { if (visit.codeCompileUnit.Namespaces[i].Types.Count == 0) { visit.codeCompileUnit.Namespaces.RemoveAt(i); } } TemplateCompileUnit = visit.codeCompileUnit; } } }
protected override CodeCompileUnit Parse() { ICSharpCode.NRefactory.IParser parser = ICSharpCode.NRefactory.ParserFactory.CreateParser(_designerFile); parser.Parse(); CodeDomVisitor visitor = new CodeDomVisitor(); visitor.VisitCompilationUnit(parser.CompilationUnit, null); return(visitor.codeCompileUnit); }
static void RunResolver() { byte[] data; using (var stream = File.OpenRead(@"myfile.bin")) { data = new byte[(int)stream.Length]; stream.Read(data, 0, data.Length); } // create a resolver var res = new CodeDomResolver(); // read the resolver sample into the compile unit CodeCompileUnit ccu; using (var stm = File.OpenRead(@"..\..\Resolver.cs")) ccu = SlangParser.ReadCompileUnitFrom(stm); // remember to patch it! SlangPatcher.Patch(ccu); Console.Error.WriteLine(CU.ToString(ccu)); // add the compile unit to the resolver res.CompileUnits.Add(ccu); // prepare the resolver // any time you add compile units you'll need // to call Refresh() res.Refresh(); // go through all expressions in the // graph and try to get their type CodeDomVisitor.Visit(ccu, (ctx) => { var expr = ctx.Target as CodeExpression; if (null != expr) { // we want everything except CodeTypeReferenceExpression var ctre = expr as CodeTypeReferenceExpression; if (null == ctre) { // get the scope of the expression var scope = res.GetScope(expr); CodeTypeReference ctr = res.TryGetTypeOfExpression(expr, scope); if (null != ctr) { Console.WriteLine(CU.ToString(expr) + " is type: " + CU.ToString(ctr)); Console.WriteLine("Scope Dump:"); Console.WriteLine(scope.ToString()); } } } }); }
static void RunTemplate() { // compute the primes. algorithm borrowed // from SLax at https://stackoverflow.com/questions/1510124/program-to-find-prime-numbers var primesMax = 100; var primesArr = Enumerable.Range(0, (int)Math.Floor(2.52 * Math.Sqrt(primesMax) / Math.Log(primesMax))).Aggregate( Enumerable.Range(2, primesMax - 1).ToList(), (result, index) => { var bp = result[index]; var sqr = bp * bp; result.RemoveAll(i => i >= sqr && i % bp == 0); return(result); } ).ToArray(); // read the template into the compile unit CodeCompileUnit ccu; using (var stm = File.OpenRead(@"..\..\Template.cs")) ccu = SlangParser.ReadCompileUnitFrom(stm); // patch it either before or after modifying it SlangPatcher.Patch(ccu); // find the target namespace and change it var ns = ccu.TryGetNamespace("T_NAMESPACE"); ns.Name = "TestNS"; // find the target class var type = ns.TryGetType("T_TYPE"); // change the name type.Name = "TestPrimes"; // get the Primes field: var primes = type.TryGetMember("Primes") as CodeMemberField; // change the init expression to the primes array primes.InitExpression = CU.Literal(primesArr); // fixup any references to T_NAMESPACE or T_TYPE CodeDomVisitor.Visit(ccu, (ctx) => { var ctr = ctx.Target as CodeTypeReference; if (null != ctr) { ctr.BaseType = ctr.BaseType.Replace("T_NAMESPACE", ns.Name).Replace("T_TYPE", type.Name); } }); // already patched prior // SlangPatcher.Patch(ccu); // now write the result out Console.WriteLine(CU.ToString(ccu)); }
// The .Designer partial file produced by Visual Studio and SharpDevelop // does not specify the inherited type. The type is specified in the // non-designer generated file.E.g: // // partial Form1 - in Form1.Designer.cs // partial Form1 : Form - in Form1.cs // private CodeCompileUnit MergeParse(string fileName, string codeBehindFileName) { CodeCompileUnit mergedUnit = null; // parse codebehind IParser codeBehindParser = ICSharpCode.NRefactory.ParserFactory.CreateParser(codeBehindFileName); codeBehindParser.Parse(); // get the first valid typedeclaration name CodeDomVisitor visitor = new CodeDomVisitor(); visitor.VisitCompilationUnit(codeBehindParser.CompilationUnit, null); mergedUnit = visitor.codeCompileUnit; string codeBehindNamespaceName = null; CodeTypeDeclaration codeBehindType = GetFirstValidType(visitor.codeCompileUnit, out codeBehindNamespaceName); if (codeBehindType == null) { throw new InvalidOperationException("No class with an InitializeComponent method found"); } // parse file without the method bodies IParser fileParser = ICSharpCode.NRefactory.ParserFactory.CreateParser(fileName); fileParser.ParseMethodBodies = false; fileParser.Parse(); // match declaration name from codebehind and get the type visitor = new CodeDomVisitor(); visitor.VisitCompilationUnit(fileParser.CompilationUnit, null); foreach (CodeNamespace namesp in visitor.codeCompileUnit.Namespaces) { if (namesp.Name == codeBehindNamespaceName) { foreach (CodeTypeDeclaration declaration in namesp.Types) { if (declaration.Name == codeBehindType.Name) { foreach (CodeTypeReference baseType in declaration.BaseTypes) { codeBehindType.BaseTypes.Add(baseType); } } } } } fileParser.Dispose(); codeBehindParser.Dispose(); return(mergedUnit); }
static void _Patch(CodeObjectCreateExpression oc, CodeDomVisitContext ctx, CodeDomResolver res) { if (null != oc) // we have to check to see if this is a delegate creation expression { oc.UserData.Remove("slang:unresolved"); if (1 == oc.Parameters.Count) { if (_IsDelegate(oc.Parameters[0], res)) { var del = _GetDelegateFromFields(oc, oc.Parameters[0], res); CodeDomVisitor.ReplaceTarget(ctx, del); } } } }
private void Generate(SupportedLanguage language, TextReader inputstream, OutputClass output) { IParser parser = ParserFactory.CreateParser(language, inputstream); parser.Parse(); if (parser.Errors.Count > 0) { new ExceptionDialog(null, "Error Parsing Input Code").ShowDialog(); } else if (output.CodeDomProvider != null) { CodeDomVisitor visitor = new CodeDomVisitor(); visitor.VisitCompilationUnit(parser.CompilationUnit, null); for (int i = visitor.codeCompileUnit.Namespaces.Count - 1; i >= 0; i--) { if (visitor.codeCompileUnit.Namespaces[i].Types.Count == 0) { visitor.codeCompileUnit.Namespaces.RemoveAt(i); } } CodeGeneratorOptions options = new CodeGeneratorOptions(); options.BlankLinesBetweenMembers = true; StringWriter writer = new StringWriter(); output.CodeDomProvider.GenerateCodeFromCompileUnit(visitor.codeCompileUnit, writer, options); this.scintillaOutput.Text = writer.ToString(); writer.Close(); } else { AbstractAstTransformer transformer = output.CreateTransformer(); List <ISpecial> currentSpecials = parser.Lexer.SpecialTracker.CurrentSpecials; if ((language == SupportedLanguage.CSharp) && (transformer is ToVBNetConvertVisitor)) { PreprocessingDirective.CSharpToVB(currentSpecials); } else if ((language == SupportedLanguage.VBNet) && (transformer is ToCSharpConvertVisitor)) { PreprocessingDirective.VBToCSharp(currentSpecials); } parser.CompilationUnit.AcceptVisitor(transformer, null); IOutputAstVisitor outputVisitor = output.CreatePrettyPrinter(); using (SpecialNodesInserter.Install(currentSpecials, outputVisitor)) { outputVisitor.VisitCompilationUnit(parser.CompilationUnit, null); } this.scintillaOutput.Text = outputVisitor.Text; } }
static void AddAttributes (AbstractMember member, IEnumerable<ICSharpCode.NRefactory.Ast.AttributeSection> attributes) { CodeDomVisitor domVisitor = new CodeDomVisitor (); foreach (ICSharpCode.NRefactory.Ast.AttributeSection attributeSection in attributes) { foreach (ICSharpCode.NRefactory.Ast.Attribute attribute in attributeSection.Attributes) { DomAttribute domAttribute = new DomAttribute (); domAttribute.Name = attribute.Name; domAttribute.Region = ConvertRegion (attribute.StartLocation, attribute.EndLocation); domAttribute.AttributeType = new DomReturnType (attribute.Name); member.Add (domAttribute); foreach (ICSharpCode.NRefactory.Ast.Expression exp in attribute.PositionalArguments) domAttribute.AddPositionalArgument ((CodeExpression)exp.AcceptVisitor (domVisitor, null)); foreach (ICSharpCode.NRefactory.Ast.NamedArgumentExpression nexp in attribute.NamedArguments) domAttribute.AddNamedArgument (nexp.Name, (CodeExpression)nexp.Expression.AcceptVisitor (domVisitor, null)); } } }
private static void _FillTypeMap(CodeNamespace codeNamespace, Dictionary <string, CodeTypeDeclaration> typeMap) { CodeDomVisitor.Visit(codeNamespace, (ctx) => { var td = ctx.Target as CodeTypeDeclaration; if (null != td) { foreach (CodeAttributeDeclaration decl in td.CustomAttributes) { if (0 == string.Compare("System.Xml.Serialization.XmlTypeAttribute", decl.AttributeType.BaseType, StringComparison.InvariantCulture)) { typeMap.Add(td.Name, td); break; } } } }, CodeDomVisitTargets.Types); }
static bool _HasUnresolved(CodeObject target) { if (target.UserData.Contains("slang:unresolved")) { return(true); } var result = false; CodeDomVisitor.Visit(target, (ctx) => { var co = ctx.Target as CodeObject; if (null != co && co.UserData.Contains("slang:unresolved")) { result = true; ctx.Cancel = true; } }); return(result); }
static void _Patch(CodeIndexerExpression indexer, CodeDomVisitContext ctx, CodeDomResolver resolver) { if (null != indexer) { if (indexer.TargetObject.UserData.Contains("slang:unresolved")) { return; } var ctr = resolver.GetTypeOfExpression(indexer.TargetObject); if (null != ctr.ArrayElementType && 0 < ctr.ArrayRank) { var ai = new CodeArrayIndexerExpression(indexer.TargetObject); ai.Indices.AddRange(indexer.Indices); CodeDomVisitor.ReplaceTarget(ctx, ai); //return; } indexer.UserData.Remove("slang:unresolved"); } }
private static void _FillPropFldMaps(CodeTypeDeclaration td, HashSet <string> propElem, HashSet <string> propAttr, Dictionary <string, string> fldMap) { CodeDomVisitor.Visit(td, (ctx) => { var prop = ctx.Target as CodeMemberProperty; if (null != prop) { foreach (CodeAttributeDeclaration decl in prop.CustomAttributes) { var isAttr = 0 == string.Compare("System.Xml.Serialization.XmlAttributeAttribute", decl.AttributeType.BaseType, StringComparison.InvariantCulture); var isElem = !isAttr && 0 == string.Compare("System.Xml.Serialization.XmlElementAttribute", decl.AttributeType.BaseType, StringComparison.InvariantCulture); if (isAttr || isElem) { if (0 < prop.GetStatements.Count) { var mr = prop.GetStatements[0] as CodeMethodReturnStatement; if (null != mr) { var fr = mr.Expression as CodeFieldReferenceExpression; if (null != fr) { fldMap.Add(fr.FieldName, prop.Name); if (isElem) { propElem.Add(prop.Name); } if (isAttr) { propAttr.Add(prop.Name); } } } } break; } } } }, CodeDomVisitTargets.Types | CodeDomVisitTargets.Members); }
/// <summary> /// Patches the CodeDOM tree received from the <see cref="SlangParser"/> into something more usable, by resolving type information and replacing various elements in the CodeDOM graph /// </summary> /// <param name="compileUnits">The <see cref="CodeCompileUnit"/> objects to patch</param> public static void Patch(IEnumerable <CodeCompileUnit> compileUnits) { var resolver = new CodeDomResolver(); foreach (var ccu in compileUnits) { resolver.CompileUnits.Add(ccu); } resolver.Refresh(); var working = -1; var oworking = 0; while (0 != working && oworking != working) { oworking = working; working = 0; for (int ic = resolver.CompileUnits.Count, i = 0; i < ic; ++i) { CodeDomVisitor.Visit(resolver.CompileUnits[i], (ctx) => { var co = ctx.Target as CodeObject; if (null != co && co.UserData.Contains("slang:unresolved")) { ++working; _Patch(ctx.Target as CodeFieldReferenceExpression, ctx, resolver); _Patch(ctx.Target as CodeVariableDeclarationStatement, ctx, resolver); _Patch(ctx.Target as CodeVariableReferenceExpression, ctx, resolver); _Patch(ctx.Target as CodeDelegateInvokeExpression, ctx, resolver); _Patch(ctx.Target as CodeObjectCreateExpression, ctx, resolver); _Patch(ctx.Target as CodeIndexerExpression, ctx, resolver); _Patch(ctx.Target as CodeMemberMethod, ctx, resolver); _Patch(ctx.Target as CodeMemberProperty, ctx, resolver); _Patch(ctx.Target as CodeTypeReference, ctx, resolver); } }); } resolver.Refresh(); } }
static void Demo3(CodeCompileUnit ccu) { /// now let's take our code and modify it CodeDomVisitor.Visit(ccu, (ctx) => { // we're looking for a method invocation var mi = ctx.Target as CodeMethodInvokeExpression; if (null != mi) { // ... calling WriteLine if ("WriteLine" == mi.Method?.MethodName) { // replace the passed in expression with "Hello world!" mi.Parameters.Clear(); mi.Parameters.Add(new CodePrimitiveExpression("Hello world!")); // done after the first WriteLine so we cancel ctx.Cancel = true; } } }); Console.WriteLine(CodeDomUtility.ToString(ccu)); Console.WriteLine("Press any key..."); Console.ReadKey(); Console.Clear(); }
static void Demo6() { // load the xsd XmlSchema xsd = null; using (FileStream stream = new FileStream("..\\..\\Test.xsd", FileMode.Open, FileAccess.Read)) { xsd = XmlSchema.Read(stream, null); } XmlSchemas xsds = new XmlSchemas(); xsds.Add(xsd); xsds.Compile(null, true); XmlSchemaImporter xsdImporter = new XmlSchemaImporter(xsds); // create the codedom CodeNamespace ns = new CodeNamespace(); CodeCompileUnit ccu = new CodeCompileUnit(); ccu.ReferencedAssemblies.Add(typeof(XmlTypeAttribute).Assembly.GetName().ToString()); ccu.Namespaces.Add(ns); XmlCodeExporter codeExporter = new XmlCodeExporter(ns, ccu); var maps = new List <XmlTypeMapping>(); foreach (XmlSchemaType schemaType in xsd.SchemaTypes.Values) { maps.Add(xsdImporter.ImportSchemaType(schemaType.QualifiedName)); } foreach (XmlSchemaElement schemaElement in xsd.Elements.Values) { maps.Add(xsdImporter.ImportTypeMapping(schemaElement.QualifiedName)); } foreach (XmlTypeMapping map in maps) { codeExporter.ExportTypeMapping(map); } var typeMap = new Dictionary <string, CodeTypeDeclaration>(StringComparer.InvariantCulture); _FillTypeMap(ns, typeMap); foreach (var kvp in typeMap) { var td = kvp.Value; var propElem = new HashSet <string>(StringComparer.InvariantCulture); var propAttr = new HashSet <string>(StringComparer.InvariantCulture); var fldMap = new Dictionary <string, string>(); _FillPropFldMaps(td, propElem, propAttr, fldMap); // fix up our xml type attribute foreach (CodeAttributeDeclaration d in td.CustomAttributes) { if (0 == string.Compare(d.AttributeType.BaseType, "System.Xml.Serialization.XmlAttributeAttribute", StringComparison.InvariantCulture)) { d.Arguments.Insert(0, new CodeAttributeArgument("TypeName", new CodePrimitiveExpression(td.Name))); break; } } // correct the type name td.Name = _ToNetCase(td.Name); CodeDomVisitor.Visit(td, (ctx) => { var fldRef = ctx.Target as CodeFieldReferenceExpression; if (null != fldRef && fldMap.ContainsKey(fldRef.FieldName)) { fldRef.FieldName = _ToPrivFldName(fldRef.FieldName); return; } var fld = ctx.Target as CodeMemberField; if (null != fld && fldMap.ContainsKey(fld.Name)) { fld.Name = _ToPrivFldName(fld.Name); var ctr = fld.Type; if (0 < ctr.ArrayRank) { ctr = ctr.ArrayElementType; } if (!CodeDomResolver.IsPrimitiveType(ctr)) { ctr.BaseType = _ToNetCase(ctr.BaseType); } } var prop = ctx.Target as CodeMemberProperty; if (null != prop && (propElem.Contains(prop.Name) || propAttr.Contains(prop.Name))) { var n = prop.Name; var ctr = prop.Type; if (0 < ctr.ArrayRank) { ctr = ctr.ArrayElementType; } if (!CodeDomResolver.IsPrimitiveType(ctr)) { ctr.BaseType = _ToNetCase(ctr.BaseType); } prop.Name = _ToNetCase(n); if (propElem.Contains(n)) { foreach (CodeAttributeDeclaration a in prop.CustomAttributes) { if (0 == string.Compare("System.Xml.Serialization.XmlElementAttribute", a.AttributeType.BaseType, StringComparison.InvariantCulture)) { a.Arguments.Insert(0, new CodeAttributeArgument("ElementName", new CodePrimitiveExpression(n))); break; } } } else { foreach (CodeAttributeDeclaration a in prop.CustomAttributes) { if (0 == string.Compare("System.Xml.Serialization.XmlAttributeAttribute", a.AttributeType.BaseType, StringComparison.InvariantCulture)) { a.Arguments.Insert(0, new CodeAttributeArgument("AttributeName", new CodePrimitiveExpression(n))); break; } } } } }); } // Check for invalid characters in identifiers CodeGenerator.ValidateIdentifiers(ns); // output the C# code Console.WriteLine(CodeDomUtility.ToString(ccu)); }
// Steps to load the designer: // - Parse main file // - Find other files containing parts of the form // - Parse all files and look for fields (for controls) and InitializeComponents method // - Create CodeDom objects for fields and InitializeComponents statements // - If debug build and Ctrl pressed, output CodeDom to console // - Return CodeDom objects to the .NET designer protected override CodeCompileUnit Parse() { LoggingService.Debug("NRefactoryDesignerLoader.Parse()"); lastTextContent = this.Generator.ViewContent.DesignerCodeFileContent; ParseInformation parseInfo = ParserService.GetParseInformation(this.Generator.ViewContent.DesignerCodeFile.FileName); IClass formClass; bool isFirstClassInFile; IList <IClass> parts = FindFormClassParts(parseInfo, out formClass, out isFirstClassInFile); const string missingReferenceMessage = "Your project is missing a reference to '${Name}' - please add it using 'Project > Add Reference'."; if (formClass.ProjectContent.GetClass("System.Drawing.Point", 0) == null) { throw new FormsDesignerLoadException( StringParser.Parse( missingReferenceMessage, new string[, ] { { "Name", "System.Drawing" } } )); } if (formClass.ProjectContent.GetClass("System.Windows.Forms.Form", 0) == null) { throw new FormsDesignerLoadException( StringParser.Parse( missingReferenceMessage, new string[, ] { { "Name", "System.Windows.Forms" } } )); } List <KeyValuePair <string, CompilationUnit> > compilationUnits = new List <KeyValuePair <string, CompilationUnit> >(); bool foundInitMethod = false; foreach (IClass part in parts) { string fileName = part.CompilationUnit.FileName; if (fileName == null) { continue; } bool found = false; foreach (KeyValuePair <string, CompilationUnit> entry in compilationUnits) { if (FileUtility.IsEqualFileName(fileName, entry.Key)) { found = true; break; } } if (found) { continue; } ITextBuffer fileContent; if (FileUtility.IsEqualFileName(fileName, this.Generator.ViewContent.PrimaryFileName)) { fileContent = this.Generator.ViewContent.PrimaryFileContent; } else if (FileUtility.IsEqualFileName(fileName, this.Generator.ViewContent.DesignerCodeFile.FileName)) { fileContent = new StringTextBuffer(this.Generator.ViewContent.DesignerCodeFileContent); } else { fileContent = ParserService.GetParseableFileContent(fileName); } ICSharpCode.NRefactory.IParser p = ICSharpCode.NRefactory.ParserFactory.CreateParser(language, fileContent.CreateReader()); p.Parse(); if (p.Errors.Count > 0) { throw new FormsDesignerLoadException("Syntax errors in " + fileName + ":\r\n" + p.Errors.ErrorOutput); } // Try to fix the type names to fully qualified ones FixTypeNames(p.CompilationUnit, part.CompilationUnit, ref foundInitMethod); compilationUnits.Add(new KeyValuePair <string, CompilationUnit>(fileName, p.CompilationUnit)); } if (!foundInitMethod) { throw new FormsDesignerLoadException("The InitializeComponent method was not found. Designer cannot be loaded."); } CompilationUnit combinedCu = new CompilationUnit(); NamespaceDeclaration nsDecl = new NamespaceDeclaration(formClass.Namespace); combinedCu.AddChild(nsDecl); TypeDeclaration formDecl = new TypeDeclaration(Modifiers.Public, null); nsDecl.AddChild(formDecl); formDecl.Name = formClass.Name; foreach (KeyValuePair <string, CompilationUnit> entry in compilationUnits) { foreach (object o in entry.Value.Children) { TypeDeclaration td = o as TypeDeclaration; if (td != null && td.Name == formDecl.Name) { foreach (INode node in td.Children) { formDecl.AddChild(node); } formDecl.BaseTypes.AddRange(td.BaseTypes); } if (o is NamespaceDeclaration) { foreach (object o2 in ((NamespaceDeclaration)o).Children) { td = o2 as TypeDeclaration; if (td != null && td.Name == formDecl.Name) { foreach (INode node in td.Children) { formDecl.AddChild(node); } formDecl.BaseTypes.AddRange(td.BaseTypes); } } } } } CodeDomVisitor visitor = new CodeDomVisitor(); visitor.EnvironmentInformationProvider = new ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryInformationProvider(formClass.ProjectContent); visitor.VisitCompilationUnit(combinedCu, null); // output generated CodeDOM to the console : #if DEBUG if ((Control.ModifierKeys & Keys.Control) == Keys.Control) { CodeDomVerboseOutputGenerator outputGenerator = new CodeDomVerboseOutputGenerator(); outputGenerator.GenerateCodeFromMember(visitor.codeCompileUnit.Namespaces[0].Types[0], Console.Out, null); this.CodeDomProvider.GenerateCodeFromCompileUnit(visitor.codeCompileUnit, Console.Out, null); } #endif LoggingService.Debug("NRefactoryDesignerLoader.Parse() finished"); if (!isFirstClassInFile) { MessageService.ShowWarning("The form must be the first class in the file in order for form resources be compiled correctly.\n" + "Please move other classes below the form class definition or move them to other files."); } return(visitor.codeCompileUnit); }
static void _Patch(CodeVariableReferenceExpression vr, CodeDomVisitContext ctx, CodeDomResolver resolver) { if (null != vr) { if ("NodeFlags" == vr.VariableName) { System.Diagnostics.Debugger.Break(); } var scope = resolver.GetScope(vr); if (scope.VariableTypes.ContainsKey(vr.VariableName)) { vr.UserData.Remove("slang:unresolved"); return; } // we need to replace it. if (scope.ArgumentTypes.ContainsKey(vr.VariableName)) { var a = new CodeArgumentReferenceExpression(vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, a); return; //args.Cancel = true; } else if (scope.FieldNames.Contains(vr.VariableName)) { CodeTypeReference tref; // find out where it belongs. if (scope.ThisTargets.Contains(vr.VariableName)) { var f = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, f); //return; } else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref)) { var f = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, f); //return; } return; } else if (scope.MethodNames.Contains(vr.VariableName)) { CodeTypeReference tref; // find out where it belongs. if (scope.ThisTargets.Contains(vr.VariableName)) { var m = new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, m); return; //args.Cancel = true; } if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref)) { var m = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, m); return; //args.Cancel = true; } } else if (scope.PropertyNames.Contains(vr.VariableName)) { CodeTypeReference tref; // find out where it belongs. if (scope.ThisTargets.Contains(vr.VariableName)) { var p = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, p); return; //args.Cancel = true; } else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref)) { var p = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, p); return; //args.Cancel = true; } } else if (scope.EventNames.Contains(vr.VariableName)) { CodeTypeReference tref; // find out where it belongs. if (scope.ThisTargets.Contains(vr.VariableName)) { var e = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, e); return; //args.Cancel = true; } else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref)) { var e = new CodeEventReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, e); return; //args.Cancel = true; } } return; } return; }
static CodeCompileUnit ParseInternal(TextReader codeStream) { IParser parser = ParserFactory.CreateParser( SupportedLanguage.CSharp, codeStream); parser.ParseMethodBodies = true; parser.Parse(); if (parser.Errors.Count > 0) { throw new ArgumentException(parser.Errors.ErrorOutput); } var cdv = new CodeDomVisitor(); // new CodeDomVisitor (parser.Lexer.SpecialTracker.CurrentSpecials); parser.CompilationUnit.AcceptVisitor(cdv, null); parser.Dispose(); CodeCompileUnit ccu = cdv.codeCompileUnit; //C# parser seems to insist on putting imports in the "Global" namespace; fix it up for (int i = 0; i < ccu.Namespaces.Count; i++) { CodeNamespace global = ccu.Namespaces [i]; if ((global.Name == "Global") && (global.Types.Count == 0)) { global.Name = ""; ccu.Namespaces.RemoveAt(i); ccu.Namespaces.Insert(0, global); //clear out repeat imports... for (int j = 1; j < ccu.Namespaces.Count; j++) { CodeNamespace cn = ccu.Namespaces [j]; //why can't we remove imports? will have to collect ones to keep //then clear and refill CodeNamespaceImportCollection imps = new CodeNamespaceImportCollection(); for (int m = 0; m < cn.Imports.Count; m++) { bool found = false; for (int n = 0; n < global.Imports.Count; n++) { if (global.Imports [n] == cn.Imports [m]) { found = true; } } if (!found) { imps.Add(cn.Imports [m]); } } cn.Imports.Clear(); foreach (CodeNamespaceImport imp in imps) { cn.Imports.Add(imp); } } break; } } return(ccu); }
public static int Run(string[] args, TextReader stdin, TextWriter stdout, TextWriter stderr) { // our return code var result = 0; // app parameters string inputfile = null; string outputfile = null; string codeclass = null; string codelanguage = null; string codenamespace = null; string externaltoken = null; string nfagraph = null; string dfagraph = null; bool ignorecase = false; bool noshared = false; bool ifstale = false; // our working variables TextReader input = null; TextWriter output = null; try { if (0 == args.Length) { _PrintUsage(stderr); result = -1; } else if (args[0].StartsWith("/")) { throw new ArgumentException("Missing input file."); } else { // process the command line args inputfile = args[0]; for (var i = 1; i < args.Length; ++i) { switch (args[i].ToLowerInvariant()) { case "/output": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance outputfile = args[i]; break; case "/class": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance codeclass = args[i]; break; case "/language": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance codelanguage = args[i]; break; case "/namespace": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance codenamespace = args[i]; break; case "/external": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance externaltoken = args[i]; break; case "/nfagraph": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance nfagraph = args[i]; break; case "/dfagraph": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance dfagraph = args[i]; break; case "/ignorecase": ignorecase = true; break; case "/noshared": noshared = true; break; case "/ifstale": ifstale = true; break; default: throw new ArgumentException(string.Format("Unknown switch {0}", args[i])); } } // now build it if (string.IsNullOrEmpty(codeclass)) { // default we want it to be named after the code file // otherwise we'll use inputfile if (null != outputfile) { codeclass = Path.GetFileNameWithoutExtension(outputfile); } else { codeclass = Path.GetFileNameWithoutExtension(inputfile); } } if (string.IsNullOrEmpty(codelanguage)) { if (!string.IsNullOrEmpty(outputfile)) { codelanguage = Path.GetExtension(outputfile); if (codelanguage.StartsWith(".")) { codelanguage = codelanguage.Substring(1); } } if (string.IsNullOrEmpty(codelanguage)) { codelanguage = "cs"; } } var stale = true; if (ifstale && null != outputfile) { stale = _IsStale(inputfile, outputfile); if (!stale) { stale = _IsStale(CodeBase, outputfile); } } if (!stale) { stderr.WriteLine("{0} skipped building {1} because it was not stale.", Name, outputfile); } else { if (null != outputfile) { stderr.Write("{0} is building file: {1}", Name, outputfile); } else { stderr.Write("{0} is building tokenizer.", Name); } input = new StreamReader(inputfile); var rules = new List <LexRule>(); string line; while (null != (line = input.ReadLine())) { var lc = LexContext.Create(line); lc.TrySkipCCommentsAndWhiteSpace(); if (-1 != lc.Current) { rules.Add(LexRule.Parse(lc)); } } input.Close(); input = null; LexRule.FillRuleIds(rules); var ccu = new CodeCompileUnit(); var cns = new CodeNamespace(); if (!string.IsNullOrEmpty(codenamespace)) { cns.Name = codenamespace; } ccu.Namespaces.Add(cns); var fa = _BuildLexer(rules, ignorecase, inputfile); var symbolTable = _BuildSymbolTable(rules); var symids = new int[symbolTable.Length]; for (var i = 0; i < symbolTable.Length; ++i) { symids[i] = i; } var blockEnds = _BuildBlockEnds(rules); var nodeFlags = _BuildNodeFlags(rules); if (null != nfagraph) { fa.RenderToFile(nfagraph); } fa = fa.ToDfa(); DfaEntry[] dfaTable = null; dfaTable = _ToDfaStateTable(fa, symids); if (!noshared) { if (string.IsNullOrEmpty(externaltoken)) { // import our Export/Token.cs into the library _ImportCompileUnit(Deslanged.Token, cns); } // import our Export/TableTokenizer.cs into the library _ImportCompileUnit(Deslanged.TableTokenizer, cns); } if (!string.IsNullOrEmpty(externaltoken)) { cns.Imports.Add(new CodeNamespaceImport(externaltoken)); } var origName = "Rolex."; CodeTypeDeclaration td = null; if (null == td) { td = Deslanged.TableTokenizerTemplate.Namespaces[1].Types[0]; origName += td.Name; td.Name = codeclass; CodeGenerator.GenerateSymbolConstants(td, symbolTable); } CodeDomVisitor.Visit(td, (ctx) => { var tr = ctx.Target as CodeTypeReference; if (null != tr) { if (0 == string.Compare(origName, tr.BaseType, StringComparison.InvariantCulture)) { tr.BaseType = codeclass; } } }); CodeMemberField f = null; f = CodeDomUtility.GetByName("DfaTable", td.Members) as CodeMemberField; f.InitExpression = CodeGenerator.GenerateDfaTableInitializer(dfaTable); f = CodeDomUtility.GetByName("NodeFlags", td.Members) as CodeMemberField; f.InitExpression = CodeDomUtility.Literal(nodeFlags); f = CodeDomUtility.GetByName("BlockEnds", td.Members) as CodeMemberField; f.InitExpression = CodeDomUtility.Literal(blockEnds); cns.Types.Add(td); var hasColNS = false; foreach (CodeNamespaceImport nsi in cns.Imports) { if (0 == string.Compare(nsi.Namespace, "System.Collections.Generic", StringComparison.InvariantCulture)) { hasColNS = true; break; } } if (!hasColNS) { cns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); } stderr.WriteLine(); var prov = CodeDomProvider.CreateProvider(codelanguage); var opts = new CodeGeneratorOptions(); opts.BlankLinesBetweenMembers = false; opts.VerbatimOrder = true; if (null == outputfile) { output = stdout; } else { // open the file and truncate it if necessary var stm = File.Open(outputfile, FileMode.Create); stm.SetLength(0); output = new StreamWriter(stm); } prov.GenerateCodeFromCompileUnit(ccu, output, opts); } } } // we don't like to catch in debug mode #if !DEBUG catch (Exception ex) { result = _ReportError(ex, stderr); } #endif finally { // close the input file if necessary if (null != input) { input.Close(); } // close the output file if necessary if (null != outputfile && null != output) { output.Close(); } } return(result); }
public CodeCompileUnit ConvertToCodeComlieUnit(String strText) { TextReader inputstream = new StringReader(strText); #region New //CSharpParser parser=new CSharpParser(); //CompilationUnit compilationUnit=parser.Parse( inputstream , @"D:\bbb.cs" ); //IProjectContent project=new CSharpProjectContent(); //var parsedFile=compilationUnit.ToTypeSystem(); //project=project.UpdateProjectContent( null , parsedFile ); //project=project.AddAssemblyReferences( builtInLibs.Value ); //ICompilation compilation=project.CreateCompilation(); //CodeCompileUnit cUnit=new CodeDomConvertVisitor().Convert( compilation , compilationUnit , parsedFile ); ////// Remove Unsed Namespaces //for ( int i=cUnit.Namespaces.Count-1; i>=0; i-- ) //{ // if ( cUnit.Namespaces[i].Types.Count==0 ) // cUnit.Namespaces.RemoveAt( i ); //} //return cUnit; #endregion #region Old ICSharpCode.NRefactory.IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, inputstream); parser.ParseMethodBodies = true; parser.Lexer.SkipAllComments = false; parser.Parse(); if (parser.Errors.Count > 0) { return(null); } //foreach ( var node in parser.CompilationUnit.Children ) //{ // // fix StartLocation / EndLocation // node.AcceptVisitor( new ICSharpCode.NRefactory.Visitors.SetRegionInclusionVisitor() , null ); //} CodeDomProvider codeDomProvider = new Microsoft.CSharp.CSharpCodeProvider(); CodeDomVisitor visit = new CodeDomVisitor(); visit.VisitCompilationUnit(parser.CompilationUnit, null); // Remove Unsed Namespaces for (int i = visit.codeCompileUnit.Namespaces.Count - 1; i >= 0; i--) { if (visit.codeCompileUnit.Namespaces[i].Types.Count == 0) { visit.codeCompileUnit.Namespaces.RemoveAt(i); } } return(visit.codeCompileUnit); #endregion }
static void _Patch(CodeFieldReferenceExpression fr, CodeDomVisitContext ctx, CodeDomResolver resolver) { if (null != fr) { // this probably means part of our field has been resolved, or at the very least // it does not come from a rooted var ref. if (!fr.TargetObject.UserData.Contains("slang:unresolved")) { var scope = resolver.GetScope(fr); var binder = new CodeDomBinder(scope); var t = resolver.GetTypeOfExpression(fr.TargetObject, scope); if (null != t && CodeDomResolver.IsNullOrVoidType(t) && fr.TargetObject is CodeVariableReferenceExpression) { return; // can't patch this field yet - it's part of a var reference that hasn't been filled in } var isStatic = false; var tre = fr.TargetObject as CodeTypeReferenceExpression; if (null != tre) { isStatic = true; } var tt = resolver.TryResolveType(isStatic ? tre.Type : t, scope, true); if (null == tt) { throw new InvalidOperationException(_AppendLineInfo(string.Format("The type {0} could not be resolved", t.BaseType), t)); } var td = tt as CodeTypeDeclaration; // TODO: This code could be a lot faster if we added some functionality to the binder // we're just checking to see if the method, property or field exists var m = binder.GetField(tt, fr.FieldName, _BindFlags); if (null != m) { fr.UserData.Remove("slang:unresolved"); return; } m = binder.GetEvent(tt, fr.FieldName, _BindFlags); if (null != m) { var er = new CodeEventReferenceExpression(fr.TargetObject, fr.FieldName); CodeDomVisitor.ReplaceTarget(ctx, er); return; } var ml = binder.GetMethodGroup(tt, fr.FieldName, _BindFlags); if (0 < ml.Length) { var mr = new CodeMethodReferenceExpression(fr.TargetObject, fr.FieldName); CodeDomVisitor.ReplaceTarget(ctx, mr); return; } ml = binder.GetPropertyGroup(tt, fr.FieldName, _BindFlags); if (0 < ml.Length) { var pr = new CodePropertyReferenceExpression(fr.TargetObject, fr.FieldName); CodeDomVisitor.ReplaceTarget(ctx, pr); return; } throw new InvalidProgramException(_AppendLineInfo(string.Format("Cannot deterimine the target reference {0}", fr.FieldName), fr)); } // TODO: This used to be first but I moved it here. // This shouldn't be done first because it's resolving types before fields and // that is a no no. I still need to make sure it doesn't break things var path = _GetUnresRootPathOfExpression(fr); if (null != path) { // now we have something to work with. var scope = resolver.GetScope(fr); var sa = path.Split('.'); if (1 == sa.Length) { System.Diagnostics.Debugger.Break(); throw new NotImplementedException(); } else { object t = null; string tn = null; CodeExpression tf = fr; CodeExpression ptf = null; CodeTypeReference ctr = null; for (var i = sa.Length - 1; i >= 1; --i) { tn = string.Join(".", sa, 0, i); ptf = tf; tf = _GetTargetOfExpression(tf); ctr = new CodeTypeReference(tn); t = resolver.TryResolveType(ctr, scope); if (null != t) { break; } } if (null != t) { var tt = t as Type; if (null != tt) { ctr = new CodeTypeReference(tt); } else { ctr = resolver.GetQualifiedType(ctr, scope); } // we found a type reference _SetTargetOfExpression(ptf, new CodeTypeReferenceExpression(ctr)); return; //args.Cancel = true; } } } } }
static void _Patch(CodeVariableReferenceExpression vr, CodeDomVisitContext ctx, CodeDomResolver resolver) { if (null != vr) { var scope = resolver.GetScope(vr); if (0 == string.Compare("value", vr.VariableName, StringComparison.InvariantCulture)) { // this could be a property set value reference var p = scope.Member as CodeMemberProperty; if (null != p) { var found = false; for (int ic = p.SetStatements.Count, i = 0; i < ic; ++i) { found = false; CodeDomVisitor.Visit(p.SetStatements[i], (ctx2) => { if (ctx2.Target == vr) { found = true; ctx2.Cancel = true; } }); if (found) { break; } } if (found) { CodeDomVisitor.ReplaceTarget(ctx, new CodePropertySetValueReferenceExpression()); return; } } } CodeTypeReference ctr; if (scope.VariableTypes.TryGetValue(vr.VariableName, out ctr)) { if (!CodeDomResolver.IsNullOrVoidType(ctr)) { vr.UserData.Remove("slang:unresolved"); return; } } // we need to replace it. if (scope.ArgumentTypes.ContainsKey(vr.VariableName)) { var a = new CodeArgumentReferenceExpression(vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, a); return; //args.Cancel = true; } else if (scope.FieldNames.Contains(vr.VariableName)) { CodeTypeReference tref; // find out where it belongs. if (scope.ThisTargets.Contains(vr.VariableName)) { var f = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, f); //return; } else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref)) { var f = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, f); //return; } return; } else if (scope.MethodNames.Contains(vr.VariableName)) { CodeTypeReference tref; // find out where it belongs. if (scope.ThisTargets.Contains(vr.VariableName)) { var m = new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, m); return; //args.Cancel = true; } if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref)) { var m = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, m); return; //args.Cancel = true; } } else if (scope.PropertyNames.Contains(vr.VariableName)) { CodeTypeReference tref; // find out where it belongs. if (scope.ThisTargets.Contains(vr.VariableName)) { var p = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, p); return; //args.Cancel = true; } else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref)) { var p = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, p); return; //args.Cancel = true; } } else if (scope.EventNames.Contains(vr.VariableName)) { CodeTypeReference tref; // find out where it belongs. if (scope.ThisTargets.Contains(vr.VariableName)) { var e = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, e); return; //args.Cancel = true; } else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref)) { var e = new CodeEventReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName); CodeDomVisitor.ReplaceTarget(ctx, e); return; //args.Cancel = true; } } return; } return; }
static void _Patch(CodeMemberMethod meth, CodeDomVisitContext ctx, CodeDomResolver resolver) { if (null != meth) { // TODO: make sure the member is actually public if (null == meth.PrivateImplementationType) { var scope = resolver.GetScope(meth); var td = scope.DeclaringType; var binder = new CodeDomBinder(scope); for (int ic = td.BaseTypes.Count, i = 0; i < ic; ++i) { var ctr = td.BaseTypes[i]; var t = resolver.TryResolveType(ctr, scope); if (null != t) { var ma = binder.GetMethodGroup(t, meth.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); if (0 < ma.Length) { var isIface = false; var ttd = t as CodeTypeDeclaration; if (null != ttd) { isIface = ttd.IsInterface; } else { var rrt = t as Type; isIface = rrt.IsInterface; } if (isIface) { var m = binder.SelectMethod(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, ma, _GetParameterTypes(meth.Parameters), null); if (null != m) { meth.ImplementationTypes.Add(ctr); } } } } } } meth.UserData.Remove("slang:unresolved"); if ("Main" == meth.Name && (meth.Attributes & MemberAttributes.ScopeMask) == MemberAttributes.Static) { if (0 == meth.Parameters.Count && null == meth.ReturnType || "System.Void" == meth.ReturnType.BaseType) { var epm = new CodeEntryPointMethod(); epm.Attributes = meth.Attributes; epm.LinePragma = meth.LinePragma; epm.StartDirectives.AddRange(meth.StartDirectives); epm.EndDirectives.AddRange(meth.EndDirectives); epm.Comments.AddRange(meth.Comments); epm.CustomAttributes.AddRange(meth.CustomAttributes); epm.ReturnTypeCustomAttributes.AddRange(meth.ReturnTypeCustomAttributes); epm.TypeParameters.AddRange(meth.TypeParameters); epm.PrivateImplementationType = meth.PrivateImplementationType; epm.ImplementationTypes.AddRange(meth.ImplementationTypes); epm.Name = meth.Name; epm.Statements.AddRange(meth.Statements); CodeDomVisitor.ReplaceTarget(ctx, epm); } } //return; } }
static void _Patch(CodeBinaryOperatorExpression op, CodeDomVisitContext ctx, CodeDomResolver resolver) { if (null != op) { //var rf = op.Left as CodeFieldReferenceExpression; //if (null != rf && rf.FieldName == "Reduce") // System.Diagnostics.Debugger.Break(); var scope = resolver.GetScope(op); if (CodeBinaryOperatorType.IdentityEquality == op.Operator) { if (_HasUnresolved(op.Left)) { return; } //var vop = op.Right as CodeVariableReferenceExpression; //if (null != vop && vop.VariableName == "n") // System.Diagnostics.Debugger.Break(); var tr1 = resolver.GetTypeOfExpression(op.Left); if (resolver.IsValueType(tr1)) { if (_HasUnresolved(op.Right)) { return; } var tr2 = resolver.GetTypeOfExpression(op.Right); if (resolver.IsValueType(tr2)) { var op2 = new CodeBinaryOperatorExpression(op.Left, CodeBinaryOperatorType.ValueEquality, op.Right); CodeDomVisitor.ReplaceTarget(ctx, op2); return; } } op.UserData.Remove("slang:unresolved"); } else if (CodeBinaryOperatorType.IdentityInequality == op.Operator) { if (_HasUnresolved(op.Left)) { return; } var tr1 = resolver.GetTypeOfExpression(op.Left); if (resolver.IsValueType(tr1)) { if (_HasUnresolved(op.Right)) { return; } var tr2 = resolver.GetTypeOfExpression(op.Right); if (resolver.IsValueType(tr2)) { // we have to hack the codedom because there is no value inequality op.Operator = CodeBinaryOperatorType.ValueEquality; var newOp = new CodeBinaryOperatorExpression(new CodePrimitiveExpression(false), CodeBinaryOperatorType.ValueEquality, op); CodeDomVisitor.ReplaceTarget(ctx, newOp); } } op.UserData.Remove("slang:unresolved"); } } }