public static IEnumerable <string> GetIdentifiers(string filePath) { var fileSyntax = JassParser.ParseFile(filePath); foreach (var declarationNode in fileSyntax.DeclarationList) { var declr = declarationNode.Declaration; if (declr.GlobalsBlock != null) { foreach (var globalDeclaration in declr.GlobalsBlock.GlobalDeclarationListNode) { yield return(globalDeclaration.ConstantDeclarationNode?.IdentifierNameNode.ValueText ?? globalDeclaration.VariableDeclarationNode.DeclarationNode.VariableDefinitionNode?.IdentifierNameNode.ValueText ?? globalDeclaration.VariableDeclarationNode.DeclarationNode.ArrayDefinitionNode.IdentifierNameNode.ValueText); } } else if (declr.TypeDefinition != null) { yield return(declr.TypeDefinition.NewTypeNameNode.ValueText); } else { yield return(declr.NativeFunctionDeclaration.FunctionDeclarationNode.IdentifierNode.ValueText); } } foreach (var functionNode in fileSyntax.FunctionList) { yield return(functionNode.FunctionDeclarationNode.IdentifierNode.ValueText); } }
public static void Obfuscate(string inputFile, string outputFile, params string[] referenceFiles) { var fileSyntax = JassParser.ParseFile(inputFile); File.Delete(outputFile); using (var fileStream = File.OpenWrite(outputFile)) { using (var streamWriter = new StreamWriter(fileStream, new UTF8Encoding(false, true))) { var renderer = new JassRenderer(streamWriter); renderer.SetNewlineString(true, false); renderer.Comments = false; renderer.Indentation = 0; renderer.OptionalWhitespace = false; renderer.OmitEmptyLines = true; renderer.InlineConstants = true; var renameDictionary = new Dictionary <string, string>(); var exceptions = new HashSet <string>(); exceptions.Add("main"); exceptions.Add("config"); foreach (var referenceFile in referenceFiles) { foreach (var identifier in IdentifiersProvider.GetIdentifiers(referenceFile)) { exceptions.Add(identifier); } } renderer.SetIdentifierOptimizerMethod( (s) => { // Make exceptions for init stuff, since these are called using ExecuteFunc if (exceptions.Contains(s) || s.StartsWith("jasshelper__initstructs") || s.EndsWith("__onInit")) { return(s); } if (!renameDictionary.ContainsKey(s)) { var renamed = $"j_{renameDictionary.Count}"; renameDictionary.Add(s, renamed); return(renamed); } return(renameDictionary[s]); }); renderer.Render(fileSyntax); } } }
public static bool CompileCSharpFromJass( string filePath, string assemblyName, string namespaceName, string className, MetadataReference[] metadataReferences, UsingDirectiveSyntax[] usingDirectives, out MetadataReference outReference, out UsingDirectiveSyntax outDirective, out EmitResult emitResult, OutputKind outputKind, bool applyNativeMemberAttributes = false, string outputSource = null, string outputEmit = null, string outputLuaTypes = null) { var directiveName = $"{namespaceName}.{className}"; outDirective = SyntaxFactory.UsingDirective(SyntaxFactory.Token(SyntaxKind.StaticKeyword), null, SyntaxFactory.ParseName(directiveName)); if (outputLuaTypes != null) { // These two are incompatible, because enums can't freely inherit from other types (example: igamestate and fgamestate enums inherit from gamestate). TranspileToEnumHandler.Reset(); } var fileSyntax = JassParser.ParseFile(filePath); if (outputLuaTypes != null) { // Output lua source code for JASS type definitions. TranspileTypesToLua(fileSyntax, $"{namespaceName}{className}", outputLuaTypes); } var compilationUnit = Transpile( fileSyntax, namespaceName, className, applyNativeMemberAttributes, usingDirectives).NormalizeWhitespace(); if (outputSource != null) { new FileInfo(outputSource).Directory.Create(); // Output C# source code. #pragma warning disable CA2000 // Dispose objects before losing scope CompilationHelper.SerializeTo(compilationUnit, File.OpenWrite(outputSource), false); #pragma warning restore CA2000 // Dispose objects before losing scope } var compilation = CompilationHelper.PrepareCompilation( compilationUnit, outputKind, assemblyName ?? directiveName, metadataReferences); if (outputEmit is null) { var peStream = new MemoryStream(); emitResult = compilation.Emit(peStream, options: new EmitOptions(metadataOnly: true)); // TODO: set metadataOnly to applyNativeMemberAttributes? peStream.Seek(0, SeekOrigin.Begin); if (emitResult.Success) { outReference = MetadataReference.CreateFromStream(peStream); return(true); } peStream.Dispose(); } else { new FileInfo(outputEmit).Directory.Create(); // Output .dll file. emitResult = compilation.Emit(outputEmit); if (emitResult.Success) { outReference = MetadataReference.CreateFromFile(outputEmit); return(true); } } outReference = null; return(false); }