Exemplo n.º 1
0
        public static FileSyntax ParseFile(string filePath)
        {
            var tokenizer = new JassTokenizer(File.ReadAllText(filePath));
            var parser    = new JassParser(tokenizer);

            return(parser.Parse());
        }
Exemplo n.º 2
0
        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);
            }
        }
Exemplo n.º 3
0
        public static FileSyntax ParseString(string text)
        {
            var tokenizer = new JassTokenizer(text);
            var parser    = new JassParser(tokenizer);

            return(parser.Parse());
        }
Exemplo n.º 4
0
        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);
                }
            }
        }
Exemplo n.º 5
0
        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);
        }