Example #1
0
        /// <summary>
        /// Determine that argument is optional in given call.
        /// </summary>
        /// <param name="call">Call which argument is tested.</param>
        /// <param name="argument">Argument which is tested.</param>
        /// <returns><c>true</c> if argument is optional, <c>false</c> otherwise.</returns>
        private bool isOptionalArgument(INodeAST call, INodeAST argument)
        {
            var provider = call.Source.CompilationInfo.GetProvider(call);
            var index    = call.GetArgumentIndex(argument);

            return(provider.IsOptionalArgument(index + 1));
        }
Example #2
0
        /// <summary>
        /// Get type registered for value represented by given node
        /// </summary>
        /// <param name="node">Node which type is needed</param>
        /// <returns>Type of value represented by node if registered, <c>null</c> otherwise</returns>
        internal TypeDescriptor GetNodeType(INodeAST node)
        {
            TypeDescriptor result;

            _nodeTypes.TryGetValue(node, out result);
            return(result);
        }
Example #3
0
        /// <summary>
        /// Handler called for every node that is removed (recursively from removedNode to descendants).
        /// </summary>
        /// <param name="view">View where node has been removed.</param>
        /// <param name="removedNode">Node that has been removed.</param>
        /// <param name="alreadyRemovedChild">Child that has been already removed.</param>
        private void onNodeRemoved(ExecutionView view, INodeAST removedNode, INodeAST alreadyRemovedChild = null)
        {
            if (removedNode == null)
            {
                return;
            }

            var context = EditContext(view);

            if (context.IsRemoved(removedNode))
            {
                //we have already registered remove action
                return;
            }

            //report node removing
            context.NodeRemoved(removedNode);

            //report parent removing to all children
            foreach (var removedChild in removedNode.AllChildren)
            {
                if (removedChild != alreadyRemovedChild)
                {
                    onParentRemoved(view, removedChild);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Gets the ascendant subsequences.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <returns>List&lt;ISeqAST&gt;.</returns>
        private List <ISeqAST> getAscendantSubsequences(INodeAST node)
        {
            var result = new List <ISeqAST>();

            var currentSeq = node.ContainingSequence;

            while (currentSeq != null)
            {
                result.Add(currentSeq);

                if (currentSeq.ContainingNode == null)
                {
                    break;
                }

                var currentNode = currentSeq.ContainingNode;
                while (currentNode.Parent != null)
                {
                    currentNode = currentNode.Parent;
                }

                currentSeq = currentNode.ContainingSequence;
            }

            result.Reverse();
            return(result);
        }
Example #5
0
        /// <summary>
        /// Finds the shift lines.
        /// </summary>
        /// <param name="shiftedLine">The shifted line.</param>
        /// <param name="behindLine">The behind line.</param>
        /// <param name="currentShiftedLine">The current shifted line.</param>
        /// <param name="currentBehindLine">The current behind line.</param>
        private void findShiftLines(INodeAST shiftedLine, INodeAST behindLine, out INodeAST currentShiftedLine, out INodeAST currentBehindLine)
        {
            var shiftedSubq = getAscendantSubsequences(shiftedLine);
            var behindSubq  = getAscendantSubsequences(behindLine);

            currentShiftedLine = shiftedLine;
            currentBehindLine  = behindLine;
            var minLength = Math.Min(shiftedSubq.Count, behindSubq.Count) - 1;

            for (int i = 0; i <= minLength; ++i)
            {
                var currentShifted = shiftedSubq[i];
                var currentBehind  = behindSubq[i];

                if (i == minLength || currentBehind != currentShifted)
                {
                    if (currentBehind != currentShifted)
                    {
                        //we have to use previous node
                        --i;
                    }

                    currentShiftedLine = getShiftingNode(i, shiftedSubq, currentShiftedLine);
                    currentBehindLine  = getShiftingNode(i, behindSubq, currentBehindLine);
                    break;
                }
            }
        }
Example #6
0
        private string resolveRedeclarationType(VariableInfo variable, INodeAST assignedVariable, bool canUseImpicit)
        {
            var variableType = variable.Type;

            if (variableType == null)
            {
                throw new NotSupportedException("Cannot redeclare variable, because of missing type info");
            }


            if (!variable.IsImplicitlyTyped || !canUseImpicit)
            {
                //keep convetion on explicit variable typing
                //or we cannot use implicit typing e.g. because of uninitialized variable delcaration
                return(variableType.TypeName);
            }

            var assignedType = _source.CompilationInfo.ResolveAssignType(assignedVariable);

            if (assignedType == null || assignedType.TypeName != variableType.TypeName)
            {
                //we don't know type of assignedType, or implicit type is different,
                //so whole type name is required
                return(variableType.TypeName);
            }

            //assigned type matches to variable type and implicit type convetion is used
            return(CSharpSyntax.ImplicitVariableType);
        }
Example #7
0
 public VariableLValue(VariableInfo variable, INodeAST variableNode, CompilationContext context)
     : base(context)
 {
     variable.AddVariableUsing(variableNode);
     _variable     = variable;
     _variableNode = variableNode;
 }
Example #8
0
 public LiteralValue(object literal, INodeAST literalNode, CompilationContext context)
     : base(context)
 {
     _literal     = literal;
     _literalNode = literalNode;
     _literalInfo = TypeDescriptor.Create(_literal.GetType());
 }
        /// <summary>
        /// Processes the r node.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        private bool processRNode(INodeAST node)
        {
            //require available searcher
            if (_searcher == null)
            {
                //new searcher is needed, based on current object
                if (_currentObject == null)
                {
                    //object is needed for searcher creation
                    //in current state - hierarchy has to be continuous
                    return(false);
                }

                _searcher = createMethodSearcher(_currentObject);
            }

            //search within the searcher
            dispatchByNode(_searcher, node, false);

            if (_searcher.HasResults)
            {
                //there are possible overloads for call
                return(setCalledObject(node, false));
            }
            else
            {
                //methods are not available - probably namespace
                //cascade is processed
                return(extendName(node));
            }
        }
        /// <summary>
        /// Sets the current object.
        /// </summary>
        /// <param name="calledObject">The called object.</param>
        /// <param name="currNode">The curr node.</param>
        /// <param name="dispatchSetter">if set to <c>true</c> [dispatch setter].</param>
        /// <returns><c>true</c> if current object is correctly set, <c>false</c> otherwise.</returns>
        private bool setCurrentObject(RValueProvider calledObject, INodeAST currNode, bool dispatchSetter)
        {
            if (calledObject != null && currNode != null && currNode.Indexer != null)
            {
                if (dispatchSetter)
                {
                    //nothing to do here - setters are created in LNode value processing
                }
                else
                {
                    var searcher = createMethodSearcher(calledObject);
                    searcher.Dispatch(Naming.IndexerGetter);
                    calledObject = resolveCall(calledObject, currNode, searcher.FoundResult);
                    if (calledObject == null)
                    {
                        //indexer hasn't been found
                        return(false);
                    }

                    //reset searcher, because object has been found
                    _searcher = null;
                }
            }

            _currentObject = calledObject;
            return(true);
        }
        /// <summary>
        /// Creates the setter value.
        /// </summary>
        /// <param name="currNode">The curr node.</param>
        /// <param name="overloadMethods">The overload methods.</param>
        /// <returns>SetterLValue.</returns>
        private SetterLValue createSetterValue(INodeAST currNode, IEnumerable <TypeMethodInfo> overloadMethods)
        {
            var overloads = overloadMethods.ToArray();

            //overloading on setters is not supported
            if (overloads.Length > 1)
            {
                throw CSharpSyntax.ParsingException(currNode, "Cannot select setter overload for {0}", currNode.Value);
            }

            var overload = overloads[0];

            if (!overload.IsStatic && _currentObject == null)
            {
                if (!_compiler.MethodInfo.HasThis)
                {
                    //cannot get implicit this object
                    return(null);
                }

                var implicitThis = _compiler.CreateImplicitThis(currNode);
                setCurrentObject(implicitThis, currNode, true);
            }

            var indexArguments = _compiler.GetArguments(currNode, currNode.Indexer != null);

            return(new SetterLValue(overloads[0], _currentObject, indexArguments, Context));
        }
Example #12
0
        /// <summary>
        /// Determine that current node represents call root.
        /// </summary>
        /// <param name="node">Tested node</param>
        /// <returns><c>true</c> for call root node, <c>false</c> otherwise</returns>
        public static bool IsCallRoot(this INodeAST node)
        {
            var type = node.NodeType;

            if (type != NodeTypes.hierarchy || type != NodeTypes.call)
            {
                //only hierarchy or call can be root of call
                return(false);
            }

            var current = node;

            while (current != null)
            {
                if (current.NodeType == NodeTypes.call)
                {
                    //call hierarchy has to end by call
                    return(true);
                }

                current = current.Child;
            }

            return(false);
        }
Example #13
0
        /// <summary>
        /// Determine that given node represent expression with side effect.
        /// </summary>
        /// <param name="node">Tested node.</param>
        /// <returns><c>true</c> if node represent expression with side effect, <c>false</c> otherwise.</returns>
        private bool hasSideEffect(INodeAST node)
        {
            if (node.Value == "typeof")
            {
                return(false);
            }

            if (node.IsAssign())
            {
                return(true);
            }

            if (node.IsConstructor())
            {
                //constructors has side effects only if they are looked at new node
                return(node.Value == CSharpSyntax.NewOperator);
            }

            if (node.IsCallRoot())
            {
                //calls has side effect only if theire complete - from hierarchy root
                return(true);
            }

            return(new NodeTypes[] { NodeTypes.prefixOperator, NodeTypes.postOperator }.Contains(node.NodeType));
        }
Example #14
0
        /// <summary>
        /// Get code represented by given node.
        /// </summary>
        /// <param name="node">Node which code is needed.</param>
        /// <returns>Code represented by given node.</returns>
        private string getCode(INodeAST node)
        {
            int p1, p2;

            getBorderPositions(node, out p1, out p2);

            return(OriginalCode.Substring(p1, p2 - p1));
        }
Example #15
0
        public override void AssignLiteral(object literal, INodeAST literalNode)
        {
            var storage = E.GetTemporaryVariable("const");

            E.AssignLiteral(storage, literal);
            var builder = generateAssign(storage);
            //TODO set call transformation provider
        }
Example #16
0
        /// <summary>
        /// Remove node from source in given view. Is only syntactical. Should be called only after
        /// proper node hierarchy remove handling.
        /// </summary>
        /// <param name="view">View where source node will be removed.</param>
        /// <param name="node">Node that will be removed.</param>
        private void remove(ExecutionView view, INodeAST node)
        {
            int p1, p2;

            getBorderPositions(node, out p1, out p2);

            write(view, p1, p2, "");
        }
Example #17
0
        public override void AssignReturnValue(TypeDescriptor returnedValueType, INodeAST callNode)
        {
            var storage = E.GetTemporaryVariable("ret");
            var builder = E.AssignReturnValue(storage, returnedValueType);

            builder.RemoveProvider = new AssignRemove(callNode);
            generateAssign(storage);
            //TODO set call transformation provider
        }
Example #18
0
 /// <summary>
 /// Return number of expected operands for given node.
 /// </summary>
 /// <param name="node">Node which arity is returned.</param>
 /// <returns>Arity of node.</returns>
 public int Arity(INodeAST node)
 {
     //unary nodes are resolved in context.
     if (node.NodeType == NodeTypes.binaryOperator)
     {
         return(2);
     }
     return(0);
 }
Example #19
0
 internal SourceRemoveProvider(TransformAction action, INodeAST contextNode)
 {
     if (action == null)
     {
         throw new ArgumentNullException();
     }
     _action      = action;
     _contextNode = contextNode;
 }
Example #20
0
        /// <summary>
        /// Get offset before given node.
        /// </summary>
        /// <param name="node">Resolved node.</param>
        /// <returns>Offset before node.</returns>
        private int getBeforeOffset(INodeAST node)
        {
            if (node == null)
            {
                return(0);
            }

            return(node.StartingToken.Position.Offset);
        }
Example #21
0
        /// <summary>
        /// Mark given node as removed by given child. Marked node has no chance to be
        /// preserved and has to be removed. It is possible to recursively mark parent
        /// and let be removed by the parent.
        /// </summary>
        /// <param name="view">View where node has been removed.</param>
        /// <param name="removedNode">Node that is removed.</param>
        /// <param name="markingChild">Child that marked its parent as removed.</param>
        private void markRemoved(ExecutionView view, INodeAST removedNode, INodeAST markingChild)
        {
            //report parent removing to all children except marking child
            onNodeRemoved(view, removedNode, markingChild);

            var parent     = removedNode.Parent;
            var parentType = parent == null ? NodeTypes.hierarchy : parent.NodeType;

            //detect that parent has to be marked as removed
            var removeParent = false;

            switch (parentType)
            {
            case NodeTypes.call:
                if (isOptionalArgument(parent, removedNode))
                {
                    removeParent = false;

                    //removed node is optional node of its parent
                    //check only for remaining argument delimiters
                    var argCount = parent.Arguments.Length;
                    if (argCount > 1)
                    {
                        //there is delimiter that should be also removed
                        var argIndex = parent.GetArgumentIndex(removedNode);

                        //last argument has leading delimiter, non last has trailing delimiter
                        var isLastArg      = argCount - 1 == argIndex;
                        var delimiterToken = isLastArg ? removedNode.StartingToken.Previous : removedNode.EndingToken.Next;
                        remove(view, delimiterToken);
                    }
                }
                else
                {
                    //non optional argument cannot be removed from parent
                    //so we will remove parent
                    removeParent = true;
                }
                break;

            default:
                removeParent = true;
                break;
            }

            //handle removing
            if (parent != null && removeParent)
            {
                markRemoved(view, parent, removedNode);
            }
            else
            {
                //removedNode is last removed node in hierarchy - remove it from source
                remove(view, removedNode);
            }
        }
Example #22
0
        /// <summary>
        /// Append call at new line after lineNode.
        /// </summary>
        /// <param name="view">View where transformation is processed.</param>
        /// <param name="lineNode">Node with line where call will be appended.</param>
        /// <param name="call">Prepended call.</param>
        internal void PrependCall(ExecutionView view, INodeAST lineNode, CallEditInfo call)
        {
            var callRepresentation = callToCSharp(call);

            ensureNamespaces(view, call);

            var beforeLineOffset = getBeforeOffset(lineNode);

            write(view, beforeLineOffset, callRepresentation);
        }
Example #23
0
        private INodeAST getTopNode(INodeAST node)
        {
            var currNode = node;

            while (currNode.Parent != null)
            {
                currNode = currNode.Parent;
            }
            return(currNode);
        }
Example #24
0
        internal BlockProvider(INodeAST lineNode, Source source = null)
        {
            _line   = lineNode;
            _source = _line == null ? source : _line.Source;

            if (_source == null)
            {
                throw new ArgumentNullException("source");
            }
        }
Example #25
0
        /// <summary>
        /// Determine that current node represents assign.
        /// </summary>
        /// <param name="node">Tested node</param>
        /// <returns><c>true</c> for assign nodes, <c>false</c> otherwise</returns>
        public static bool IsAssign(this INodeAST node)
        {
            var v = node.Value;

            //note that => ,<=, >= are not assigns
            return
                (v.EndsWith("=") &&
                 !v.Contains('>') &&
                 !v.Contains('<'));
        }
        /// <summary>
        /// Processes the l node.
        /// </summary>
        /// <param name="currNode">The curr node.</param>
        /// <returns>SetterLValue.</returns>
        private SetterLValue processLNode(INodeAST currNode)
        {
            dispatchByNode(_searcher, currNode, true);

            if (_searcher.HasResults)
            {
                return(createSetterValue(currNode, _searcher.FoundResult));
            }

            return(null);
        }
Example #27
0
        /// <summary>
        /// Rewrite given node with code representation of given value.
        /// </summary>
        /// <param name="view">View where transformation is processed.</param>
        /// <param name="node">Node that is rewritten.</param>
        /// <param name="value">Value which rewrite given node.</param>
        internal void Rewrite(ExecutionView view, INodeAST node, object value)
        {
            preserveSideEffect(view, node);

            int p1, p2;

            getBorderPositions(node, out p1, out p2);


            write(view, p1, p2, toCSharp(value));
        }
Example #28
0
        /// <summary>
        /// Gets the shifting node.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="subqChain">The subq chain.</param>
        /// <param name="defaultNode">The default node.</param>
        /// <returns>INodeAST.</returns>
        private INodeAST getShiftingNode(int index, List <ISeqAST> subqChain, INodeAST defaultNode)
        {
            var i = index + 1;

            if (i >= subqChain.Count)
            {
                return(defaultNode);
            }

            return(getTopParent(subqChain[i].ContainingNode));
        }
Example #29
0
        /// <summary>
        /// Gets the top parent.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <returns>INodeAST.</returns>
        private INodeAST getTopParent(INodeAST node)
        {
            var current = node.Parent;

            while (current.Parent != null)
            {
                current = current.Parent;
            }

            return(current);
        }
Example #30
0
        /// <summary>
        /// Find position which can be used for inserting statement before nodes statement.
        /// </summary>
        /// <param name="node">Node for that is searched position for inserting previous statement.</param>
        /// <returns>Position before nodes statement.</returns>
        internal int BeforeStatementOffset(INodeAST node)
        {
            var current = node;

            while (current.Parent != null)
            {
                current = current.Parent;
            }

            return(current.StartingToken.Position.Offset);
        }