コード例 #1
0
ファイル: OtherExpressions.cs プロジェクト: Beier/Omnium
        public override void ExitNativeMethodInvocationExpression(NativeMethodInvocationExpression nativeMethodInvocationExpression)
        {
            var arguments      = nativeMethodInvocationExpression.Arguments.ToList();
            var parameterTypes = nativeMethodInvocationExpression.ParameterTypes.ToList();

            for (int i = 0; i < nativeMethodInvocationExpression.Arguments.Count(); i++)
            {
                var fromType = arguments[i].Type;
                var toType   = parameterTypes[i];
                if (!fromType.IsAssignableTo(toType))
                {
                    Errors.Add(new CompilationError(arguments[i].Context, $"Can not assign {fromType} to {toType}"));
                }
            }
        }
コード例 #2
0
        private void RegisterNativeFunction(MethodInvocationExpression methodInvocationExpression)
        {
            var context           = methodInvocationExpression.Context;
            var memberExpression  = (MemberExpression)methodInvocationExpression.Base;
            var matchGroups       = nativeFunctionDefinitionRegex.Match(memberExpression.Name).Groups;
            var numberOfArguments = int.Parse(matchGroups[1].Value);
            var hasReturnType     = matchGroups[2].Value == "Function";
            var expectedNumberOfGenericArguments = numberOfArguments + (hasReturnType ? 1 : 0);

            if (!ValidateSignature <SourceFile>(methodInvocationExpression, expectedNumberOfGenericArguments, 4))
            {
                return;
            }

            if (!(methodInvocationExpression.Arguments.First() is StringLiteral namExpression))
            {
                Errors.Add(new CompilationError(context, "First argument must be a string literal."));
                return;
            }

            if (methodInvocationExpression.Arguments.Skip(1).Take(2).Any(x => !(x is BooleanLiteral)))
            {
                Errors.Add(new CompilationError(context, "Second and third argument must be boolean literals."));
                return;
            }

            var nativeMethodName = namExpression.Text.Substring(1, namExpression.Text.Length - 2);
            var readsState       = ((BooleanLiteral)methodInvocationExpression.Arguments.AtIndex(1)).Value;
            var changesState     = ((BooleanLiteral)methodInvocationExpression.Arguments.AtIndex(1)).Value;

            if (NativeMethods.ModifyingControlFlow.Contains(nativeMethodName))
            {
                Errors.Add(new CompilationError(context,
                                                "Native methods that modify control flow are restricted. Use if/for/foreach/while to modify control flow."));
            }

            var typescriptNames          = new List <string>();
            var typescriptNameExpression = methodInvocationExpression.Arguments.Skip(3).First();

            while (true)
            {
                if (typescriptNameExpression is MemberExpression typescriptNameMemberExpression)
                {
                    typescriptNames.Insert(0, typescriptNameMemberExpression.Name);
                    typescriptNameExpression = typescriptNameMemberExpression.Base;
                }
                else if (typescriptNameExpression is SimpleNameExpression typescriptNameSimpleExpression)
                {
                    typescriptNames.Insert(0, typescriptNameSimpleExpression.Name);
                    break;
                }
                else
                {
                    Errors.Add(new CompilationError(context, "Last argument can only consist of simple names. Ex. Math.abs"));
                    break;
                }
            }

            var container = (INode)methodInvocationExpression.NearestAncestorOfType <Root>();

            for (int i = 0; i < typescriptNames.Count - 1; i++)
            {
                var module = container.Children.OfType <ModuleDeclaration>().SingleOrDefault(x => x.Name == typescriptNames[i]);
                if (module == null)
                {
                    module = new ModuleDeclaration(context, typescriptNames[i], new INode[0]);
                    container.AddChild(module);
                }

                container = module;
            }

            var parameterTypes = methodInvocationExpression.GenericTypes.Take(numberOfArguments).ToList();
            var returnType     = hasReturnType ? methodInvocationExpression.GenericTypes.Last() : new VoidType(context);
            var nativeMethodInvocationExpression = new NativeMethodInvocationExpression(
                context,
                nativeMethodName,
                returnType,
                readsState,
                changesState,
                false,
                parameterTypes.SelectMany((x, i) => new INode[]
                                          { AstCloner.Clone(x), new SimpleNameExpression(context, "param" + i) })
                );
            var statement = hasReturnType
                ? (IStatement) new ReturnStatement(context, nativeMethodInvocationExpression.Yield())
                : new ExpressionStatement(context, nativeMethodInvocationExpression);


            var methodDeclaration = new MethodDeclaration(
                context,
                typescriptNames.Last(),
                parameterTypes.Select((x, i) => new VariableDeclaration(context, "param" + i, AstCloner.Clone(x).Yield()))
                .Concat <INode>(returnType.Yield())
                .Concat(new BlockStatement(context, statement.Yield()).Yield())
                );

            methodDeclaration.Modifiers.Add(MemberModifier.Static);
            container.AddChild(
                methodDeclaration
                );
            methodInvocationExpression.Remove();
        }
コード例 #3
0
 public override INode VisitNativeMethodInvocationExpression(NativeMethodInvocationExpression nativeMethodInvocationExpression)
 {
     return(new NativeMethodInvocationExpression(nativeMethodInvocationExpression.Context, nativeMethodInvocationExpression.NativeMethodName, nativeMethodInvocationExpression.Type, nativeMethodInvocationExpression.ReadsState, nativeMethodInvocationExpression.ChangesState, nativeMethodInvocationExpression.ModifiesControlFlow, nativeMethodInvocationExpression.Children.Select(Visit)));
 }
コード例 #4
0
ファイル: TreeVoidWalker.cs プロジェクト: Beier/Omnium
 public virtual void ExitNativeMethodInvocationExpression(NativeMethodInvocationExpression nativeMethodInvocationExpression)
 {
 }
コード例 #5
0
ファイル: TreeValueWalker.cs プロジェクト: Beier/Omnium
 public virtual T VisitNativeMethodInvocationExpression(NativeMethodInvocationExpression nativeMethodInvocationExpression)
 {
     return(VisitChildren(nativeMethodInvocationExpression));
 }