public override XElement Persist(IDocumentAccessor accessor)
 {
     return new XElement("Category",
         new XAttribute("type", _value.GetType().ToString()),
         new XAttribute("value", _value.ToString()),
         base.Persist(accessor));
 }
Example #2
0
 public XElement Persist(IDocumentAccessor accessor)
 {
     return new XElement(Component.NamespaceOpenMIv2 + "Argument",
         new XAttribute("Key", Key),
         new XAttribute("Value", Value),
         new XAttribute("ReadOnly", ReadOnly));
 }
 public void Indent(IDocumentAccessor document, bool keepEmptyLines)
 {
     if (document == null)
     {
         throw new ArgumentNullException("document");
     }
 }
        public void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            var identity = Persistence.Identity.Parse(xElement, accessor);

            SetIdentity(identity);

            var xComponentType = xElement
                .Elements("ComponentType")
                .SingleOrDefault();

            ComponentType.Initialise(xComponentType, accessor);

            var xEngineType = xElement
                .Elements("EngineType")
                .SingleOrDefault();

            EngineType.Initialise(xEngineType, accessor);

            UseNativeEngine = Utilities.Xml.GetAttribute(xElement, "useNativeEngine", false);

            Arguments = Persistence.Arguments
                .Parse(xElement, accessor)
                .ToList();

            Inputs = Persistence.Inputs
                .Parse(xElement, accessor)
                .ToList();

            Outputs = Persistence.Outputs
                .Parse(xElement, accessor)
                .ToList();
        }
        public void Reformat(IDocumentAccessor doc, IndentationSettings settings)
        {
            Init();

            while (doc.MoveNext())
                Step(doc, settings);
        }
        public void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            ISpatialDefinition spatial;
            bool hasZ, hasM;
            ElementType = Persistence.ElementSet.Parse(xElement, accessor, out spatial, out hasZ, out hasM);
            SetSpatial(spatial);
            HasZ = hasZ;
            HasM = hasM;

            string relative = xElement.Value;

            var uri = new Uri(accessor.Uri, relative);

            var selafin = new FileInfo(uri.LocalPath);

            Selafin = new Selafin(selafin);

               var argIdSelafin =  Utilities.Xml.GetAttribute(xElement, "argIdSelafin");

               Arguments = new IArgument[] {
                new ArgumentFile(new Identity(argIdSelafin, "Selafin file"), selafin),
                }.ToList();

            Initialise();
        }
        public Category(XElement xElement, IDocumentAccessor accessor)
            : base(xElement.Elements("Describes").Single(), accessor)
        {
            Utilities.Xml.ValidElement(xElement, "Category");

            Type type = Type.GetType(Utilities.Xml.GetAttribute(xElement, "type"));
            _value = Convert.ChangeType(Utilities.Xml.GetAttribute(xElement, "value"), type);
        }
Example #8
0
            public void Initialise(XElement xElement, IDocumentAccessor accessor)
            {
                Contract.Requires(xElement != null, "xElement != null");

                Key = Utilities.Xml.GetAttribute(xElement, "Key");
                Value = Utilities.Xml.GetAttribute(xElement, "Value");
                ReadOnly = Utilities.Xml.GetAttribute(xElement, "ReadOnly", false);
            }
Example #9
0
        char lastRealChar;         // last non-comment char

        public void Reformat(IDocumentAccessor doc, IndentationSettings set)
        {
            Init();

            while (doc.Next())
            {
                Step(doc, set);
            }
        }
        public override void Initialise(string initialisingXml, IDocumentAccessor accessor)
        {
            base.Initialise(initialisingXml, accessor);

            _caption = ArgumentCaption;

            _timeDelta = (double)Argument(SimpleComponent.GetArgumentIdentity(
                SimpleComponent.ConsumerArgs.TimeDelta)).Value;
        }
        public void Reformat(IDocumentAccessor document, IndentationSettings settings)
        {
            this.Initialize();

            while (document.MoveNext())
            {
                this.Step(document, settings);
            }
        }
        /// <summary>
        /// Simple implementation of interface FluidEarth2.Sdk.Interfaces.IEngine::Initialise()
        /// 
        /// Overide if specific additional functionality required.
        /// </summary>
        /// <param name="initialisingXml">See FluidEarth2.Sdk.BaseEngine</param>
        /// <param name="accessor">See FluidEarth2.Sdk.BaseEngine</param>
        public override void Initialise(string initialisingXml, IDocumentAccessor accessor)
        {
            base.Initialise(initialisingXml, accessor);

            _horizon = new Time(ArgumentTimeHorizon);
            _timeCurrent = _horizon.StampAsModifiedJulianDay;

            if (double.IsNegativeInfinity(_timeCurrent))
                throw new Exception("Time horizon start is unbounded");
        }
        public override void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            base.Initialise(xElement, accessor);

            IndexMap = xElement
                .Elements("Indexes")
                .Select(x => Persistence.Values<int>.Parse(x, accessor))
                .ToArray();
        }
		/// <summary>
		/// Performs indentation using the specified document accessor.
		/// </summary>
		/// <param name="document">Object used for accessing the document line-by-line</param>
		/// <param name="keepEmptyLines">Specifies whether empty lines should be kept</param>
		public void Indent(IDocumentAccessor document, bool keepEmptyLines)
		{
			if (document == null)
				throw new ArgumentNullException("document");
			IndentationSettings settings = new IndentationSettings();
			settings.IndentString = this.IndentationString;
			settings.LeaveEmptyLines = keepEmptyLines;
			
			IndentationReformatter r = new IndentationReformatter();
			r.Reformat(document, settings);
		}
        public virtual void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            ISpatialDefinition spatial;
            bool hasZ, hasM;
            ElementType = Persistence.ElementSet.Parse(xElement, accessor, out spatial, out hasZ, out hasM);
            SetSpatial(spatial);
            HasZ = hasZ;
            HasM = hasM;
        }
        public void Indent(IDocumentAccessor document, bool keepEmptyLines)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }
            var settings    = new IndentationSettings(this.IndentationString, keepEmptyLines);
            var reformatter = new IndentationReformatter();

            reformatter.Reformat(document, settings);
        }
        public void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            Identity = Persistence.Identity.Parse(xElement, accessor);
            ValueDefinition = Persistence.ValueDefinition.Parse(xElement, accessor);
            SpatialDefinition = Persistence.SpatialDefinition.Parse(xElement, accessor);
            TimeSet = Persistence.TimeSet.Parse(xElement, accessor);

            Component = null;
            Provider = null;
        }
        /// <summary>
        /// Performs indentation using the specified document accessor.
        /// </summary>
        /// <param name="document">Object used for accessing the document line-by-line</param>
        /// <param name="indentationString">The string used for indentation.</param>
        /// <param name="keepEmptyLines">Specifies whether empty lines should be kept</param>
        private void Indent(IDocumentAccessor document, string indentationString, bool keepEmptyLines)
        {
            if (document == null)
                throw new ArgumentNullException(nameof(document));

            IndentationSettings settings = new IndentationSettings();
            settings.IndentString = indentationString;
            settings.LeaveEmptyLines = keepEmptyLines;

            CSharpIndentationReformatter r = new CSharpIndentationReformatter();
            r.Reformat(document, settings);
        }
		/// <summary>
		///     Performs indentation using the specified document accessor.
		/// </summary>
		/// <param name="document">Object used for accessing the document line-by-line</param>
		/// <param name="keepEmptyLines">Specifies whether empty lines should be kept</param>
		public int Indent(IDocumentAccessor document, bool keepEmptyLines, int caretOffset)
		{
			if (document == null)
				throw new ArgumentNullException("document");
			var settings = new IndentationSettings();
			settings.IndentString = IndentationString;
			settings.LeaveEmptyLines = keepEmptyLines;

			var r = new IndentationReformatter();
			r.Reformat(document, settings);
			return caretOffset;
		}
        public override void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            base.Initialise(xElement, accessor);

            Ids = xElement
                .Elements(Persistence.Identity.XName)
                .Select(i => Persistence.Identity.Parse(i, accessor))
                .ToArray();

            ElementCount = Ids.Length;
        }
 public void Indent(IDocumentAccessor document, bool keepEmptyLines)
 {
     if (document == null)
     {
         throw new ArgumentNullException("document");
     }
     var set = new IndentationSettings
     {
         IndentString = IndentationString,
         LeaveEmptyLines = keepEmptyLines
     };
     var indentationClass = new IndentationClass();
     indentationClass.Reformat(document, set);
 }
        public virtual void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            Identity = Persistence.Identity.Parse(xElement, accessor);
            ValueDefinition = Persistence.ValueDefinition.Parse(xElement, accessor);
            SpatialDefinition = Persistence.SpatialDefinition.Parse(xElement, accessor);
            TimeSet = Persistence.TimeSet.Parse(xElement, accessor);

            Component = null;
            Provider = null;

            _valueSetConverterTime = Persistence.Parse<IValueSetConverterTime>("ValueSetConverterTime", xElement, accessor);
            _valueSetConverterTime.ExchangeItem = this;
        }
Example #23
0
        /// <summary>
        /// Performs indentation using the specified document accessor.
        /// </summary>
        /// <param name="document">Object used for accessing the document line-by-line</param>
        /// <param name="keepEmptyLines">Specifies whether empty lines should be kept</param>
        public void Indent(IDocumentAccessor document, bool keepEmptyLines)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }
            IndentationSettings settings = new IndentationSettings();

            settings.IndentString    = this.IndentationString;
            settings.LeaveEmptyLines = keepEmptyLines;

            IndentationReformatter r = new IndentationReformatter();

            r.Reformat(document, settings);
        }
        public LinkableComponentOpenMIV1Wrapper(ILinkableComponentVersion1 component1, 
            IDocumentAccessor accessor,
            List<Utilities.Standard1.Argument1> args1)
            : base(new Identity(component1.ComponentID,
                    component1.ModelID + " [OpenMIv1]", component1.ComponentDescription),
                new ExternalType(typeof(LinkableComponentOpenMIV1Wrapper)),
                new ExternalType(typeof(EngineProxy)))
        {
            Description += "\r\nConverted from OpenMI Standard 1";

            DocumentAccessor = accessor;

            var uriPersistence = InitialiseArguments(component1, args1);

            ConstuctComponent(component1, uriPersistence, args1);
        }
        /// <summary>
        /// Performs indentation using the specified document accessor.
        /// </summary>
        /// <param name="document">Object used for accessing the document line-by-line</param>
        /// <param name="indentationString">The string used for indentation.</param>
        /// <param name="keepEmptyLines">Specifies whether empty lines should be kept</param>
        private void Indent(IDocumentAccessor document, string indentationString, bool keepEmptyLines)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            IndentationSettings settings = new IndentationSettings();

            settings.IndentString    = indentationString;
            settings.LeaveEmptyLines = keepEmptyLines;

            HlslIndentationReformatter r = new HlslIndentationReformatter();

            r.Reformat(document, settings);
        }
Example #26
0
        /// <summary>
        ///     Performs indentation using the specified document accessor.
        /// </summary>
        /// <param name="document">Object used for accessing the document line-by-line</param>
        /// <param name="keepEmptyLines">Specifies whether empty lines should be kept</param>
        public int Indent(IDocumentAccessor document, bool keepEmptyLines, int caretOffset)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }
            var settings = new IndentationSettings();

            settings.IndentString    = IndentationString;
            settings.LeaveEmptyLines = keepEmptyLines;

            var r = new IndentationReformatter();

            r.Reformat(document, settings);
            return(caretOffset);
        }
        internal static bool TrimEnd(this IDocumentAccessor document)
        {
            var line = document.Text;

            if (!char.IsWhiteSpace(line[line.Length - 1]))
            {
                return(false);
            }
            if (line.EndsWith("// ", StringComparison.Ordinal) ||
                line.EndsWith("* ", StringComparison.Ordinal))
            {
                return(false);
            }

            document.Text = line.TrimEnd();
            return(true);
        }
Example #28
0
        static bool TrimEnd(IDocumentAccessor doc)
        {
            string line = doc.Text;

            if (!Char.IsWhiteSpace(line[line.Length - 1]))
            {
                return(false);
            }

            // one space after an empty comment is allowed
            if (line.EndsWith("// ", StringComparison.Ordinal) || line.EndsWith("* ", StringComparison.Ordinal))
            {
                return(false);
            }

            doc.Text = line.TrimEnd();
            return(true);
        }
        public BaseExchangeItem(IBaseLinkableComponent component, XElement xElement, IDocumentAccessor accessor)
            : base(Persistence.Identity.Parse(xElement.Elements(Persistence.Identity.XName).Single(), accessor))
        {
            Contract35.Requires(xElement.Name == BaseExchangeItem.XName);

            Component = component;
            //            _componentId = Utilities.Xml.GetAttribute(xElement, "componentId");

            if (xElement.Elements(Persistence.ValueDefinition.XName).SingleOrDefault() != null)
                ValueDefinition = Persistence.ValueDefinition.Parse(
                    xElement.Element(Persistence.ValueDefinition.XName), accessor);

            _valueSetConverter = null;

            foreach (XElement xUserVariable in xElement.Elements("UserVariable"))
                _userVariables.Add(
                    Utilities.Xml.GetAttribute(xUserVariable, "key"),
                    Utilities.Xml.GetAttribute(xUserVariable, "value"));
        }
        public void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            ISpatialDefinition spatial;
            bool hasZ, hasM;
            ElementType = Persistence.ElementSet.Parse(xElement, accessor, out spatial, out hasZ, out hasM);
            SetSpatial(spatial);
            HasZ = hasZ;
            HasM = hasM;

            Arguments = Persistence.Arguments
                .Parse(xElement, accessor)
                .ToList();

            GridParameters = new ParametersGridRegular();
            GridParameters.Initialise(xElement, accessor);

            ((ArgumentValueGridRegular)Arguments[0]).Value = GridParameters;
        }
        public LinkableComponentFluidEarthV1Wrapper(ILinkableComponentVersion1 component1, 
            IDocumentAccessor accessor,
            List<Utilities.Standard1.Argument1> args1)
            : base(new Identity(component1.ComponentID,
                    component1.ModelID + " [FluidEarthV1]", component1.ComponentDescription),
                new ExternalType(typeof(LinkableComponentOpenMIV1Wrapper)),
                new ExternalType(typeof(IProxyEngine5)),
                true)
        {
            _includeUpdateTimeInterval = false;

            Description += "\r\nUsing FluidEarth V1";

            DocumentAccessor = accessor;

            var uriPersistence = InitialiseArguments(component1, args1);

            SetDefaultArguments();

            ConstuctComponent(component1, uriPersistence, args1);
        }
        public void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            string inter = Utilities.Xml.GetAttribute(xElement, "interface");

            _interface = (Interface)Enum.Parse(typeof(Interface), inter);

            _nativeDllImplementingNetAssembly = null;

            XElement xdllDotNetStub = xElement
                .Elements("ExternalType")
                .SingleOrDefault();

            if (xdllDotNetStub != null)
            {
                _nativeDllImplementingNetAssembly = new ExternalType(accessor);
                _nativeDllImplementingNetAssembly.Initialise(xdllDotNetStub, accessor);
            }

            _debuggerLaunch = Utilities.Xml.GetAttribute(xElement, "debuggerLaunch", false);
        }
 public BaseComponentWithEngine(XElement xElement, IDocumentAccessor accessor)
 {
     Initialise(xElement, accessor);
 }
        public virtual XElement Persist(IDocumentAccessor accessor)
        {
            int traceTo = (int)_writeTo;

            var xml = new XElement(XName,
                Persistence.BaseComponent.Persist(this, accessor),
                new XAttribute("useNativeDllArgument", _useNativeDll),
                new XAttribute("traceTo", traceTo.ToString()));

            if (_derivedComponentType != null)
                xml.Add(new XElement("DerivedComponentType", _derivedComponentType.Persist(accessor)));
            if (_engineType != null)
                xml.Add(new XElement("EngineType", _engineType.Persist(accessor)));

            return xml;
        }
        public virtual void Initialise(XElement xElement, IDocumentAccessor accessor)
        {
            xElement = Persistence.ThisOrSingleChild(XName, xElement);

            IEnumerable<IArgument> arguments;
            IEnumerable<IBaseInput> inputs;
            IEnumerable<IBaseOutput> outputs;

            Identity = Persistence.BaseComponent.Parse(xElement, accessor, out arguments, out inputs, out outputs);

            Arguments = arguments.ToList();

            SetArgCaption();

            Inputs = inputs.ToList();
            Outputs = outputs.ToList();

            foreach (var i in Inputs)
                if (i is BaseExchangeItem)
                    ((BaseExchangeItem)i).Component = this;

            foreach (var i in Outputs)
                if (i is BaseExchangeItem)
                    ((BaseExchangeItem)i).Component = this;

            _useNativeDll = Utilities.Xml.GetAttribute(xElement, "useNativeDllArgument", false);

            int traceTo = int.Parse(Utilities.Xml.GetAttribute(xElement, "traceTo"));

            _writeTo = (WriteTo)traceTo;

            var derivedComponentType = xElement
                .Elements("DerivedComponentType")
                .SingleOrDefault();

            _derivedComponentType = derivedComponentType != null
                ? new ExternalType(derivedComponentType, accessor)
                : null;

            var engineType = xElement
                .Elements("EngineType")
                .SingleOrDefault();

            _engineType = engineType != null
                ? new ExternalType(engineType, accessor)
                : null;

            _engine = null;

            _activeInputs = new List<IBaseInput>();
            _activeOutputs = new List<IBaseOutput>();
        }
 public virtual XElement EngineInitialisingXml(IDocumentAccessor accessor)
 {
     return new XElement("Engine",
         _engineType.Persist(accessor),
         Persistence.Arguments.Persist(Arguments, accessor));
 }
        public void Step(IDocumentAccessor doc, IndentationSettings set)
        {
            string line = doc.Text;
            if (set.LeaveEmptyLines && line.Length == 0) return; // leave empty lines empty
            line = line.TrimStart();

            StringBuilder indent = new StringBuilder();
            if (line.Length == 0) {
                // Special treatment for empty lines:
                if (blockComment || (inString && verbatim))
                    return;
                indent.Append(block.InnerIndent);
                indent.Append(Repeat(set.IndentString, block.OneLineBlock));
                if (block.Continuation)
                    indent.Append(set.IndentString);
                if (doc.Text != indent.ToString())
                    doc.Text = indent.ToString();
                return;
            }

            if (TrimEnd(doc))
                line = doc.Text.TrimStart();

            Block oldBlock = block;
            bool startInComment = blockComment;
            bool startInString = (inString && verbatim);

            #region Parse char by char
            lineComment = false;
            inChar = false;
            escape = false;
            if (!verbatim) inString = false;

            lastRealChar = '\n';

            char lastchar = ' ';
            char c = ' ';
            char nextchar = line[0];
            for (int i = 0; i < line.Length; i++) {
                if (lineComment) break; // cancel parsing current line

                lastchar = c;
                c = nextchar;
                if (i + 1 < line.Length)
                    nextchar = line[i + 1];
                else
                    nextchar = '\n';

                if (escape) {
                    escape = false;
                    continue;
                }

                #region Check for comment/string chars
                switch (c) {
                    case '/':
                        if (blockComment && lastchar == '*')
                            blockComment = false;
                        if (!inString && !inChar) {
                            if (!blockComment && nextchar == '/')
                                lineComment = true;
                            if (!lineComment && nextchar == '*')
                                blockComment = true;
                        }
                        break;
                    case '#':
                        if (!(inChar || blockComment || inString))
                            lineComment = true;
                        break;
                    case '"':
                        if (!(inChar || lineComment || blockComment)) {
                            inString = !inString;
                            if (!inString && verbatim) {
                                if (nextchar == '"') {
                                    escape = true; // skip escaped quote
                                    inString = true;
                                } else {
                                    verbatim = false;
                                }
                            } else if (inString && lastchar == '@') {
                                verbatim = true;
                            }
                        }
                        break;
                    case '\'':
                        if (!(inString || lineComment || blockComment)) {
                            inChar = !inChar;
                        }
                        break;
                    case '\\':
                        if ((inString && !verbatim) || inChar)
                            escape = true; // skip next character
                        break;
                }
                #endregion

                if (lineComment || blockComment || inString || inChar) {
                    if (wordBuilder.Length > 0)
                        block.LastWord = wordBuilder.ToString();
                    wordBuilder.Length = 0;
                    continue;
                }

                if (!Char.IsWhiteSpace(c) && c != '[' && c != '/') {
                    if (block.Bracket == '{')
                        block.Continuation = true;
                }

                if (Char.IsLetterOrDigit(c)) {
                    wordBuilder.Append(c);
                } else {
                    if (wordBuilder.Length > 0)
                        block.LastWord = wordBuilder.ToString();
                    wordBuilder.Length = 0;
                }

                #region Push/Pop the blocks
                switch (c) {
                    case '{':
                        block.ResetOneLineBlock();
                        blocks.Push(block);
                        block.StartLine = doc.LineNumber;
                        if (block.LastWord == "switch") {
                            block.Indent(set.IndentString + set.IndentString);
                            /* oldBlock refers to the previous line, not the previous block
                             * The block we want is not available anymore because it was never pushed.
                             * } else if (oldBlock.OneLineBlock) {
                            // Inside a one-line-block is another statement
                            // with a full block: indent the inner full block
                            // by one additional level
                            block.Indent(set, set.IndentString + set.IndentString);
                            block.OuterIndent += set.IndentString;
                            // Indent current line if it starts with the '{' character
                            if (i == 0) {
                                oldBlock.InnerIndent += set.IndentString;
                            }*/
                        } else {
                            block.Indent(set);
                        }
                        block.Bracket = '{';
                        break;
                    case '}':
                        while (block.Bracket != '{') {
                            if (blocks.Count == 0) break;
                            block = blocks.Pop();
                        }
                        if (blocks.Count == 0) break;
                        block = blocks.Pop();
                        block.Continuation = false;
                        block.ResetOneLineBlock();
                        break;
                    case '(':
                    case '[':
                        blocks.Push(block);
                        if (block.StartLine == doc.LineNumber)
                            block.InnerIndent = block.OuterIndent;
                        else
                            block.StartLine = doc.LineNumber;
                        block.Indent(Repeat(set.IndentString, oldBlock.OneLineBlock) +
                                     (oldBlock.Continuation ? set.IndentString : "") +
                                     (i == line.Length - 1 ? set.IndentString : new String(' ', i + 1)));
                        block.Bracket = c;
                        break;
                    case ')':
                        if (blocks.Count == 0) break;
                        if (block.Bracket == '(') {
                            block = blocks.Pop();
                            if (IsSingleStatementKeyword(block.LastWord))
                                block.Continuation = false;
                        }
                        break;
                    case ']':
                        if (blocks.Count == 0) break;
                        if (block.Bracket == '[')
                            block = blocks.Pop();
                        break;
                    case ';':
                    case ',':
                        block.Continuation = false;
                        block.ResetOneLineBlock();
                        break;
                    case ':':
                        if (block.LastWord == "case"
                            || line.StartsWith("case ", StringComparison.Ordinal)
                            || line.StartsWith(block.LastWord + ":", StringComparison.Ordinal))
                        {
                            block.Continuation = false;
                            block.ResetOneLineBlock();
                        }
                        break;
                }

                if (!Char.IsWhiteSpace(c)) {
                    // register this char as last char
                    lastRealChar = c;
                }
                #endregion
            }
            #endregion

            if (wordBuilder.Length > 0)
                block.LastWord = wordBuilder.ToString();
            wordBuilder.Length = 0;

            if (startInString) return;
            if (startInComment && line[0] != '*') return;
            if (doc.Text.StartsWith("//\t", StringComparison.Ordinal) || doc.Text == "//")
                return;

            if (line[0] == '}') {
                indent.Append(oldBlock.OuterIndent);
                oldBlock.ResetOneLineBlock();
                oldBlock.Continuation = false;
            } else {
                indent.Append(oldBlock.InnerIndent);
            }

            if (indent.Length > 0 && oldBlock.Bracket == '(' && line[0] == ')') {
                indent.Remove(indent.Length - 1, 1);
            } else if (indent.Length > 0 && oldBlock.Bracket == '[' && line[0] == ']') {
                indent.Remove(indent.Length - 1, 1);
            }

            if (line[0] == ':') {
                oldBlock.Continuation = true;
            } else if (lastRealChar == ':' && indent.Length >= set.IndentString.Length) {
                if (block.LastWord == "case" || line.StartsWith("case ", StringComparison.Ordinal) || line.StartsWith(block.LastWord + ":", StringComparison.Ordinal))
                    indent.Remove(indent.Length - set.IndentString.Length, set.IndentString.Length);
            } else if (lastRealChar == ')') {
                if (IsSingleStatementKeyword(block.LastWord)) {
                    block.OneLineBlock++;
                }
            } else if (lastRealChar == 'e' && block.LastWord == "else") {
                block.OneLineBlock = Math.Max(1, block.PreviousOneLineBlock);
                block.Continuation = false;
                oldBlock.OneLineBlock = block.OneLineBlock - 1;
            }

            if (doc.IsReadOnly) {
                // We can't change the current line, but we should accept the existing
                // indentation if possible (=if the current statement is not a multiline
                // statement).
                if (!oldBlock.Continuation && oldBlock.OneLineBlock == 0 &&
                    oldBlock.StartLine == block.StartLine &&
                    block.StartLine < doc.LineNumber && lastRealChar != ':')
                {
                    // use indent StringBuilder to get the indentation of the current line
                    indent.Length = 0;
                    line = doc.Text; // get untrimmed line
                    for (int i = 0; i < line.Length; ++i) {
                        if (!Char.IsWhiteSpace(line[i]))
                            break;
                        indent.Append(line[i]);
                    }
                    // /* */ multiline comments have an extra space - do not count it
                    // for the block's indentation.
                    if (startInComment && indent.Length > 0 && indent[indent.Length - 1] == ' ') {
                        indent.Length -= 1;
                    }
                    block.InnerIndent = indent.ToString();
                }
                return;
            }

            if (line[0] != '{') {
                if (line[0] != ')' && oldBlock.Continuation && oldBlock.Bracket == '{')
                    indent.Append(set.IndentString);
                indent.Append(Repeat(set.IndentString, oldBlock.OneLineBlock));
            }

            // this is only for blockcomment lines starting with *,
            // all others keep their old indentation
            if (startInComment)
                indent.Append(' ');

            if (indent.Length != (doc.Text.Length - line.Length) ||
                !doc.Text.StartsWith(indent.ToString(), StringComparison.Ordinal) ||
                Char.IsWhiteSpace(doc.Text[indent.Length]))
            {
                doc.Text = indent.ToString() + line;
            }
        }
        static bool TrimEnd(IDocumentAccessor doc)
        {
            string line = doc.Text;
            if (!Char.IsWhiteSpace(line[line.Length - 1])) return false;

            // one space after an empty comment is allowed
            if (line.EndsWith("// ", StringComparison.Ordinal) || line.EndsWith("* ", StringComparison.Ordinal))
                return false;

            doc.Text = line.TrimEnd();
            return true;
        }
Example #39
0
 public ListController(IDocumentAccessor <UserDocument> documentStore)
 {
     this.documentStore = documentStore;
 }
Example #40
0
 public AnalysisController(IDocumentAccessor <UserDocument> documentStore, IWorkItemsService userWorkItemsService, IHostingEnvironment hostingEnvironment)
 {
     this.documentStore        = documentStore;
     this.userWorkItemsService = userWorkItemsService;
     this.hostingEnvironment   = hostingEnvironment;
 }
Example #41
0
        private void Step(IDocumentAccessor doc, IndentationSettings settings)
        {
            string line = doc.Text;

            if (settings.LeaveEmptyLines && line.Length == 0)
            {
                // Leave empty lines empty.
                _lineCommentStart = 0;
                return;
            }

            line = line.TrimStart();
            if (line.Length == 0)
            {
                _lineCommentStart = 0;
                if (_inBlockComment || _inVerbatimString)
                {
                    // Examples:
                    //
                    //  /* comment
                    //                      <-- HERE
                    //     comment
                    //  */
                    //
                    //  string s = @"text
                    //                      <-- HERE
                    //  text";
                    return;
                }

                _indent.Clear();
                _indent.Append(_block.InnerIndent);
                _indent.Append(Repeat(settings.IndentString, _block.OneLineBlock));
                if (_block.Continuation)
                {
                    // Example:
                    //
                    //   method(
                    //                      <-- HERE
                    //
                    _indent.Append(settings.IndentString);
                }

                // Apply indentation to current line.
                if (doc.Text.Length != _indent.Length) // Check length first to avoid unnecessary ToString().
                {
                    string text = _indent.ToString();
                    // ReSharper disable once RedundantCheckBeforeAssignment
                    if (doc.Text != text)
                    {
                        doc.Text = text;
                    }
                }

                return;
            }

            if (TrimEnd(doc))
            {
                line = doc.Text.TrimStart();
            }

            // oldBlock is the block at the start of the line.
            // _block is the block at the current character.
            Block oldBlock = _block;

            bool startInComment       = _inBlockComment;
            bool startInString        = _inVerbatimString;
            bool inLineComment        = false;
            int  lastLineCommentStart = _lineCommentStart;

            _lineCommentStart = 0;
            bool inString     = _inVerbatimString;
            bool inChar       = false;
            bool isEscapeChar = false;

            char lastRealChar = '\n'; // The last non-comment character.



            char previousChar;
            char currentChar = ' ';
            char nextChar    = line[0];

            for (int i = 0; i < line.Length; i++)
            {
                if (inLineComment)
                {
                    // Cancel parsing current line.
                    break;
                }

                previousChar = currentChar;
                currentChar  = nextChar;
                if (i + 1 < line.Length)
                {
                    nextChar = line[i + 1];
                }
                else
                {
                    nextChar = '\n';
                }

                // Skip escape characters.
                if (isEscapeChar)
                {
                    // Example:
                    //
                    //   char c = '\t';
                    //              ^
                    //             HERE
                    //
                    isEscapeChar = false;
                    continue;
                }

                // ----- Check for comment, preprocessor directive, string, character.
                switch (currentChar)
                {
                // Check for preprocessor directive.
                case '#':
                    if (!(_inBlockComment || inString || inChar))
                    {
                        inLineComment = true;
                    }
                    break;

                // Check for comment.
                case '/':
                    if (_inBlockComment && previousChar == '*')
                    {
                        _inBlockComment = false;
                    }

                    if (!inString && !inChar)
                    {
                        if (!_inBlockComment && nextChar == '/')
                        {
                            inLineComment     = true;
                            _lineCommentStart = i;
                        }
                        if (!inLineComment && nextChar == '*')
                        {
                            _inBlockComment = true;
                        }
                    }
                    break;

                // Check for string.
                case '"':
                    if (!(_inBlockComment || inLineComment || inChar))
                    {
                        inString = !inString;
                        if (!inString && _inVerbatimString)
                        {
                            if (nextChar == '"')
                            {
                                // Example:
                                //
                                //   string s = @"Printing ""double quotation"" ...";
                                //                         ^
                                //                        HERE
                                //
                                isEscapeChar = true;     // Skip escaped quote.
                                inString     = true;
                            }
                            else
                            {
                                // Example:
                                //
                                //   string s = @"Printing ""double quotation"" ...";
                                //                                                 ^
                                //                                                HERE
                                //
                                _inVerbatimString = false;
                            }
                        }
                        else if (inString)
                        {
                            // Example:
                            //
                            //   string s = "Text";
                            //              ^
                            //             HERE
                            //
                            //   string s = @"Printing ""double quotation"" ...";
                            //               ^
                            //              HERE
                            //
                            _inVerbatimString = (previousChar == '@');
                        }
                        else
                        {
                            // Example:
                            //
                            //   string s = "Text";
                            //                   ^
                            //                  HERE
                            //
                            _inVerbatimString = false;
                        }
                    }
                    break;

                // Check for character.
                case '\'':
                    if (!(_inBlockComment || inLineComment || inString))
                    {
                        inChar = !inChar;
                    }
                    break;

                // Check for escape character.
                case '\\':
                    if ((inString && !_inVerbatimString) || inChar)
                    {
                        isEscapeChar = true;     // Skip next character at start of loop.
                    }
                    break;
                }

                Debug.Assert(!_inVerbatimString || _inVerbatimString && inString, "When _inVerbatimString is set, inString needs to be set.");

                // At this point the following variables are set:
                //   _inDirective, _inBlockComment,
                //   inLineComment, lineCommentStart,
                //   _inVerbatimString, _inString,
                //   inChar, _isEscapeChar

                if (_inBlockComment || inLineComment || inString || inChar)
                {
                    // Store last word before directive/comment/string/char and continue
                    // with next character.
                    if (_wordBuilder.Length > 0)
                    {
                        _block.LastWord = _wordBuilder.ToString();
                        _wordBuilder.Clear();
                    }

                    continue;
                }

                if (!Char.IsWhiteSpace(currentChar) && currentChar != '[' && currentChar != '/')
                {
                    if (_block.Bracket == '{')
                    {
                        // The current line potentially contains a statement. If the statement
                        // is not completed in this line, it the next line is a continuation.
                        _block.Continuation = true;
                    }
                }

                if (Char.IsLetterOrDigit(currentChar))
                {
                    _wordBuilder.Append(currentChar);
                }
                else
                {
                    if (_wordBuilder.Length > 0)
                    {
                        _block.LastWord = _wordBuilder.ToString();
                        _wordBuilder.Clear();
                    }
                }

                // ----- Push/pop the blocks.
                switch (currentChar)
                {
                case '{':
                    _block.ResetOneLineBlock();
                    _blocks.Push(_block);
                    _block.StartLine = doc.LineNumber;
                    if (_block.LastWord == "switch")
                    {
                        _block.Indent(settings.IndentString + settings.IndentString);

                        /* oldBlock refers to the previous line, not the previous block
                         * The block we want is not available anymore because it was never pushed.
                         * } else if (oldBlock.OneLineBlock) {
                         * // Inside a one-line-block is another statement
                         * // with a full block: indent the inner full block
                         * // by one additional level
                         * block.Indent(settings, settings.IndentString + settings.IndentString);
                         * block.OuterIndent += settings.IndentString;
                         * // Indent current line if it starts with the '{' character
                         * if (i == 0) {
                         * oldBlock.InnerIndent += settings.IndentString;
                         * }*/
                    }
                    else
                    {
                        if (i == line.Length - 1)
                        {
                            // Example:
                            //
                            //   if (condition) {
                            //                  ^
                            //                 HERE
                            //
                            _block.Indent(settings.IndentString);
                        }
                        else
                        {
                            // Example:
                            //
                            //   char[] array = { value, value,
                            //                  ^
                            //                 HERE
                            //
                            // Align subsequent lines with first value.
                            _block.Indent(new string(' ', i + 2));
                        }
                    }
                    _block.Bracket = '{';
                    break;

                case '}':
                    while (_block.Bracket != '{')
                    {
                        if (_blocks.Count == 0)
                        {
                            break;
                        }
                        _block = _blocks.Pop();
                    }
                    if (_blocks.Count == 0)
                    {
                        break;
                    }
                    _block = _blocks.Pop();
                    _block.Continuation = false;
                    _block.ResetOneLineBlock();
                    break;

                case '(':
                case '[':
                    _blocks.Push(_block);
                    if (_block.StartLine == doc.LineNumber)
                    {
                        // Example:
                        //
                        //   ???
                        //
                        _block.InnerIndent = _block.OuterIndent;
                    }
                    else
                    {
                        _block.StartLine = doc.LineNumber;
                    }

                    _indent.Clear();

                    // New block may be part of line continuation.
                    if (oldBlock.Continuation)
                    {
                        _indent.Append(settings.IndentString);
                    }

                    // New block may be part to one-line-block.
                    _indent.Append(Repeat(settings.IndentString, oldBlock.OneLineBlock));

                    if (i == line.Length - 1)
                    {
                        // Example:
                        //
                        //   method(
                        //         ^
                        //        HERE
                        //
                        _indent.Append(settings.IndentString);
                    }
                    else
                    {
                        // Example:
                        //
                        //   method(param,
                        //         ^
                        //        HERE
                        //
                        // Align subsequent lines with first parameter.
                        _indent.Append(' ', i + 1);
                    }

                    _block.Indent(_indent.ToString());
                    _block.Bracket = currentChar;
                    break;

                case ')':
                    if (_blocks.Count == 0)
                    {
                        break;
                    }
                    if (_block.Bracket == '(')
                    {
                        // Example:
                        //
                        //   method(param);
                        //               ^
                        //              HERE
                        //
                        _block = _blocks.Pop();

                        if (IsSingleStatementKeyword(_block.LastWord))
                        {
                            // Example:
                            //
                            //   if (condition)
                            //                ^
                            //               HERE
                            _block.Continuation = false;
                        }
                    }
                    break;

                case ']':
                    if (_blocks.Count == 0)
                    {
                        break;
                    }
                    if (_block.Bracket == '[')
                    {
                        // Example:
                        //
                        //   array[index]
                        //              ^
                        //             HERE
                        _block = _blocks.Pop();
                    }
                    break;

                case ';':
                case ',':
                    // Example:
                    //
                    //   statement;
                    //            ^
                    //           HERE
                    _block.Continuation = false;
                    _block.ResetOneLineBlock();
                    break;

                case ':':
                    if (_block.LastWord == "case" ||
                        line.StartsWith("case ", StringComparison.Ordinal) ||
                        line.StartsWith(_block.LastWord + ":", StringComparison.Ordinal))
                    {
                        // Examples:
                        //
                        //   case 1:
                        //         ^
                        //        HERE
                        //
                        //   label:
                        //        ^
                        //       HERE
                        _block.Continuation = false;
                        _block.ResetOneLineBlock();
                    }
                    break;
                }

                if (!Char.IsWhiteSpace(currentChar))
                {
                    // Register this character as last non-comment characater.
                    lastRealChar = currentChar;
                }
            }


            // At this point the line is parsed.

            if (_wordBuilder.Length > 0)
            {
                _block.LastWord = _wordBuilder.ToString();
                _wordBuilder.Clear();
            }

            if (startInComment && line[0] != '*')
            {
                return;
            }
            if (startInString)
            {
                return;
            }
            if (doc.Text.StartsWith("//\t", StringComparison.Ordinal) || doc.Text == "//")
            {
                return;
            }



            // Note: Line continuations, one-line-blocks, and multiline block comments
            // are not handled here. They are handled explicitly when the indentation
            // is applied.

            _indent.Clear();
            if (line[0] == '}')
            {
                // Example:
                //
                //   {
                //     statement;
                //     statement;
                //   }                    <-- HERE
                //
                _indent.Append(oldBlock.OuterIndent);
                oldBlock.ResetOneLineBlock();
                oldBlock.Continuation = false;
            }
            else
            {
                // Example:
                //
                //   {
                //     statement;
                //     statement;         <-- HERE
                //   }
                //
                _indent.Append(oldBlock.InnerIndent);
            }

            if (_indent.Length > 0 && oldBlock.Bracket == '(' && line[0] == ')')
            {
                // Example:
                //
                //   Method(param,
                //          param
                //         );             <-- HERE
                //
                _indent.Remove(_indent.Length - 1, 1);
            }
            else if (_indent.Length > 0 && oldBlock.Bracket == '[' && line[0] == ']')
            {
                // Example:
                //
                //   array[index0,
                //         index1
                //        ];             <-- HERE
                //
                _indent.Remove(_indent.Length - 1, 1);
            }

            if (line[0] == ':')
            {
                // Example:
                //
                //   ???
                //
                oldBlock.Continuation = true;
            }
            else if (lastRealChar == ':' && _indent.Length >= settings.IndentString.Length)
            {
                if (_block.LastWord == "case" ||
                    line.StartsWith("case ", StringComparison.Ordinal) ||
                    line.StartsWith(_block.LastWord + ":", StringComparison.Ordinal))
                {
                    // Examples:
                    //
                    //   switch (variable)
                    //   {
                    //     case 1:          <-- HERE
                    //       statement;
                    //   }
                    //
                    //   label:             <-- HERE
                    //     statement;
                    _indent.Remove(_indent.Length - settings.IndentString.Length, settings.IndentString.Length);
                }
            }
            else if (lastRealChar == ')')
            {
                if (IsSingleStatementKeyword(_block.LastWord))
                {
                    // Example:
                    //
                    //   if (condition)     <--- HERE
                    //
                    _block.OneLineBlock++;
                }
            }
            else if (lastRealChar == 'e' && _block.LastWord == "else")
            {
                // Example:
                //
                //   if (condition)
                //     statement;
                //   else                 <-- HERE
                //     statement;
                //
                // PreviousOneLineBlock stores the indentation level used by the previous
                // if-branch. Use the same indentation on the following else-branch.
                _block.OneLineBlock   = Math.Max(1, _block.PreviousOneLineBlock);
                _block.Continuation   = false;
                oldBlock.OneLineBlock = _block.OneLineBlock - 1;
            }



            if (doc.IsReadOnly)
            {
                // ----- Read-only line. (Not in selected text region.)
                // We can't change the current line, but we should accept the existing
                // indentation if possible (=if the current statement is not a multiline
                // statement).
                if (!oldBlock.Continuation &&
                    oldBlock.OneLineBlock == 0 &&
                    oldBlock.StartLine == _block.StartLine &&
                    _block.StartLine < doc.LineNumber &&
                    lastRealChar != ':')
                {
                    // Use indent StringBuilder to get the indentation of the current line.
                    _indent.Clear();
                    line = doc.Text; // get untrimmed line
                    for (int i = 0; i < line.Length; ++i)
                    {
                        if (!Char.IsWhiteSpace(line[i]))
                        {
                            break;
                        }
                        _indent.Append(line[i]);
                    }

                    // /* */ multiline block comments have an extra space - do not count it
                    // for the block's indentation. (The extra space is applied explicitly below.)
                    if (startInComment && _indent.Length > 0 && _indent[_indent.Length - 1] == ' ')
                    {
                        _indent.Length -= 1;
                    }

                    _block.InnerIndent = _indent.ToString();
                }
            }
            else
            {
                // ----- Reformat current line.
                if (line[0] == '#')
                {
                    // Do not indent preprocessor directives.
                    _indent.Clear();
                }
                else if (lastLineCommentStart > 0 &&
                         line.StartsWith("//", StringComparison.Ordinal) &&
                         (line.Length <= 2 || char.IsWhiteSpace(line[2])))    // Ignore commented code such as "//statement;".
                {
                    // Special treatment to align dangling comments.
                    // Example:
                    //
                    //   statement;  // comment
                    //               // comment            <-- HERE
                    //               // comment
                    _indent.Append(' ', lastLineCommentStart);
                    _lineCommentStart = lastLineCommentStart;
                }
                else if (line[0] != '{')
                {
                    // Handle line continuation.
                    if (line[0] != ')' && oldBlock.Continuation && oldBlock.Bracket == '{')
                    {
                        // Variant #1: Reformat line. (Overrides user-defined indentation.)
                        //_indent.Append(settings.IndentString);

                        // Variant #2: Ignore line. (Keep any user-defined indentation.)
                        return;
                    }

                    // Handle one-line-blocks.
                    _indent.Append(Repeat(settings.IndentString, oldBlock.OneLineBlock));
                }

                // Handle multiline block comments.
                if (startInComment)
                {
                    Debug.Assert(line[0] == '*', "Other cases should have been handled above.");

                    // This is a multiline block comment.
                    // Example:
                    //
                    //   /* comment
                    //    * comment         <-- HERE
                    //
                    // Add ' ' to align the '*' characters.
                    _indent.Append(' ');
                }

                // Check whether line already has correct indentation to avoid unnecessary change.
                if (_indent.Length != (doc.Text.Length - line.Length) ||
                    Char.IsWhiteSpace(doc.Text[_indent.Length]) ||
                    !doc.Text.StartsWith(_indent.ToString(), StringComparison.Ordinal))
                {
                    doc.Text = _indent.Append(line).ToString();
                }
            }
        }
Example #42
0
        public void Step(IDocumentAccessor doc, IndentationSettings set)
        {
            string line = doc.Text;

            if (set.LeaveEmptyLines && line.Length == 0)
            {
                return;                                                      // leave empty lines empty
            }
            line = line.TrimStart();

            StringBuilder indent = new StringBuilder();

            if (line.Length == 0)
            {
                // Special treatment for empty lines:
                if (blockComment || (inString && verbatim))
                {
                    return;
                }
                indent.Append(block.InnerIndent);
                indent.Append(Repeat(set.IndentString, block.OneLineBlock));
                if (block.Continuation)
                {
                    indent.Append(set.IndentString);
                }
                if (doc.Text != indent.ToString())
                {
                    doc.Text = indent.ToString();
                }
                return;
            }

            if (TrimEnd(doc))
            {
                line = doc.Text.TrimStart();
            }

            Block oldBlock       = block;
            bool  startInComment = blockComment;
            bool  startInString  = (inString && verbatim);

            #region Parse char by char
            lineComment = false;
            inChar      = false;
            escape      = false;
            if (!verbatim)
            {
                inString = false;
            }

            lastRealChar = '\n';

            char lastchar = ' ';
            char c        = ' ';
            char nextchar = line[0];
            for (int i = 0; i < line.Length; i++)
            {
                if (lineComment)
                {
                    break;                              // cancel parsing current line
                }
                lastchar = c;
                c        = nextchar;
                if (i + 1 < line.Length)
                {
                    nextchar = line[i + 1];
                }
                else
                {
                    nextchar = '\n';
                }

                if (escape)
                {
                    escape = false;
                    continue;
                }

                #region Check for comment/string chars
                switch (c)
                {
                case '/':
                    if (blockComment && lastchar == '*')
                    {
                        blockComment = false;
                    }
                    if (!inString && !inChar)
                    {
                        if (!blockComment && nextchar == '/')
                        {
                            lineComment = true;
                        }
                        if (!lineComment && nextchar == '*')
                        {
                            blockComment = true;
                        }
                    }
                    break;

                case '#':
                    if (!(inChar || blockComment || inString))
                    {
                        lineComment = true;
                    }
                    break;

                case '"':
                    if (!(inChar || lineComment || blockComment))
                    {
                        inString = !inString;
                        if (!inString && verbatim)
                        {
                            if (nextchar == '"')
                            {
                                escape   = true;                                       // skip escaped quote
                                inString = true;
                            }
                            else
                            {
                                verbatim = false;
                            }
                        }
                        else if (inString && lastchar == '@')
                        {
                            verbatim = true;
                        }
                    }
                    break;

                case '\'':
                    if (!(inString || lineComment || blockComment))
                    {
                        inChar = !inChar;
                    }
                    break;

                case '\\':
                    if ((inString && !verbatim) || inChar)
                    {
                        escape = true;                                 // skip next character
                    }
                    break;
                }
                #endregion

                if (lineComment || blockComment || inString || inChar)
                {
                    if (wordBuilder.Length > 0)
                    {
                        block.LastWord = wordBuilder.ToString();
                    }
                    wordBuilder.Length = 0;
                    continue;
                }

                if (!Char.IsWhiteSpace(c) && c != '[' && c != '/')
                {
                    if (block.Bracket == '{')
                    {
                        block.Continuation = true;
                    }
                }

                if (Char.IsLetterOrDigit(c))
                {
                    wordBuilder.Append(c);
                }
                else
                {
                    if (wordBuilder.Length > 0)
                    {
                        block.LastWord = wordBuilder.ToString();
                    }
                    wordBuilder.Length = 0;
                }

                #region Push/Pop the blocks
                switch (c)
                {
                case '{':
                    block.ResetOneLineBlock();
                    blocks.Push(block);
                    block.StartLine = doc.LineNumber;
                    if (block.LastWord == "switch")
                    {
                        block.Indent(set.IndentString + set.IndentString);

                        /* oldBlock refers to the previous line, not the previous block
                         * The block we want is not available anymore because it was never pushed.
                         * } else if (oldBlock.OneLineBlock) {
                         * // Inside a one-line-block is another statement
                         * // with a full block: indent the inner full block
                         * // by one additional level
                         * block.Indent(set, set.IndentString + set.IndentString);
                         * block.OuterIndent += set.IndentString;
                         * // Indent current line if it starts with the '{' character
                         * if (i == 0) {
                         *      oldBlock.InnerIndent += set.IndentString;
                         * }*/
                    }
                    else
                    {
                        block.Indent(set);
                    }
                    block.Bracket = '{';
                    break;

                case '}':
                    while (block.Bracket != '{')
                    {
                        if (blocks.Count == 0)
                        {
                            break;
                        }
                        block = blocks.Pop();
                    }
                    if (blocks.Count == 0)
                    {
                        break;
                    }
                    block = blocks.Pop();
                    block.Continuation = false;
                    block.ResetOneLineBlock();
                    break;

                case '(':
                case '[':
                    blocks.Push(block);
                    if (block.StartLine == doc.LineNumber)
                    {
                        block.InnerIndent = block.OuterIndent;
                    }
                    else
                    {
                        block.StartLine = doc.LineNumber;
                    }
                    block.Indent(Repeat(set.IndentString, oldBlock.OneLineBlock) +
                                 (oldBlock.Continuation ? set.IndentString : "") +
                                 (i == line.Length - 1 ? set.IndentString : new String(' ', i + 1)));
                    block.Bracket = c;
                    break;

                case ')':
                    if (blocks.Count == 0)
                    {
                        break;
                    }
                    if (block.Bracket == '(')
                    {
                        block = blocks.Pop();
                        if (IsSingleStatementKeyword(block.LastWord))
                        {
                            block.Continuation = false;
                        }
                    }
                    break;

                case ']':
                    if (blocks.Count == 0)
                    {
                        break;
                    }
                    if (block.Bracket == '[')
                    {
                        block = blocks.Pop();
                    }
                    break;

                case ';':
                case ',':
                    block.Continuation = false;
                    block.ResetOneLineBlock();
                    break;

                case ':':
                    if (block.LastWord == "case" ||
                        line.StartsWith("case ", StringComparison.Ordinal) ||
                        line.StartsWith(block.LastWord + ":", StringComparison.Ordinal))
                    {
                        block.Continuation = false;
                        block.ResetOneLineBlock();
                    }
                    break;
                }

                if (!Char.IsWhiteSpace(c))
                {
                    // register this char as last char
                    lastRealChar = c;
                }
                #endregion
            }
            #endregion

            if (wordBuilder.Length > 0)
            {
                block.LastWord = wordBuilder.ToString();
            }
            wordBuilder.Length = 0;

            if (startInString)
            {
                return;
            }
            if (startInComment && line[0] != '*')
            {
                return;
            }
            if (doc.Text.StartsWith("//\t", StringComparison.Ordinal) || doc.Text == "//")
            {
                return;
            }

            if (line[0] == '}')
            {
                indent.Append(oldBlock.OuterIndent);
                oldBlock.ResetOneLineBlock();
                oldBlock.Continuation = false;
            }
            else
            {
                indent.Append(oldBlock.InnerIndent);
            }

            if (indent.Length > 0 && oldBlock.Bracket == '(' && line[0] == ')')
            {
                indent.Remove(indent.Length - 1, 1);
            }
            else if (indent.Length > 0 && oldBlock.Bracket == '[' && line[0] == ']')
            {
                indent.Remove(indent.Length - 1, 1);
            }

            if (line[0] == ':')
            {
                oldBlock.Continuation = true;
            }
            else if (lastRealChar == ':' && indent.Length >= set.IndentString.Length)
            {
                if (block.LastWord == "case" || line.StartsWith("case ", StringComparison.Ordinal) || line.StartsWith(block.LastWord + ":", StringComparison.Ordinal))
                {
                    indent.Remove(indent.Length - set.IndentString.Length, set.IndentString.Length);
                }
            }
            else if (lastRealChar == ')')
            {
                if (IsSingleStatementKeyword(block.LastWord))
                {
                    block.OneLineBlock++;
                }
            }
            else if (lastRealChar == 'e' && block.LastWord == "else")
            {
                block.OneLineBlock    = Math.Max(1, block.PreviousOneLineBlock);
                block.Continuation    = false;
                oldBlock.OneLineBlock = block.OneLineBlock - 1;
            }

            if (doc.IsReadOnly)
            {
                // We can't change the current line, but we should accept the existing
                // indentation if possible (=if the current statement is not a multiline
                // statement).
                if (!oldBlock.Continuation && oldBlock.OneLineBlock == 0 &&
                    oldBlock.StartLine == block.StartLine &&
                    block.StartLine < doc.LineNumber && lastRealChar != ':')
                {
                    // use indent StringBuilder to get the indentation of the current line
                    indent.Length = 0;
                    line          = doc.Text;            // get untrimmed line
                    for (int i = 0; i < line.Length; ++i)
                    {
                        if (!Char.IsWhiteSpace(line[i]))
                        {
                            break;
                        }
                        indent.Append(line[i]);
                    }
                    // /* */ multiline comments have an extra space - do not count it
                    // for the block's indentation.
                    if (startInComment && indent.Length > 0 && indent[indent.Length - 1] == ' ')
                    {
                        indent.Length -= 1;
                    }
                    block.InnerIndent = indent.ToString();
                }
                return;
            }

            if (line[0] != '{')
            {
                if (line[0] != ')' && oldBlock.Continuation && oldBlock.Bracket == '{')
                {
                    indent.Append(set.IndentString);
                }
                indent.Append(Repeat(set.IndentString, oldBlock.OneLineBlock));
            }

            // this is only for blockcomment lines starting with *,
            // all others keep their old indentation
            if (startInComment)
            {
                indent.Append(' ');
            }

            if (indent.Length != (doc.Text.Length - line.Length) ||
                !doc.Text.StartsWith(indent.ToString(), StringComparison.Ordinal) ||
                Char.IsWhiteSpace(doc.Text[indent.Length]))
            {
                doc.Text = indent.ToString() + line;
            }
        }
        public void Step(IDocumentAccessor document, IndentationSettings settings)
        {
            var line = document.Text;

            if (settings.LeaveEmptyLines && line.Length == 0)
            {
                return;
            }
            line = line.TrimStart();

            var indent = new StringBuilder();

            if (line.Length == 0)
            {
                if (this._blockComment)
                {
                    return;
                }
                indent.Append(this._block.InnerIndent);
                indent.Append(settings.IndentString.Repeat(this._block.OneLineBlock));
                if (this._block.Continuation)
                {
                    indent.Append(settings.IndentString);
                }
                if (document.Text != indent.ToString())
                {
                    document.Text = indent.ToString();
                }
                return;
            }

            if (document.TrimEnd())
            {
                line = document.Text.TrimStart();
            }

            var oldBlock       = this._block;
            var startInComment = this._blockComment;

            this._lineComment = false;
            this._escape      = false;

            this._lastNonCommentChar = '\n';

            var reader = new CharReader(line);

            var cha  = ' ';
            var prev = '\0';
            var next = '\n';

            var indented = false;

            while (reader.IsRemainChar)
            {
                cha  = reader.Get();
                prev = reader.Backward;
                next = reader.Ahead;

                if (this._lineComment)
                {
                    break;
                }
                if (this._escape)
                {
                    this._escape = false;
                    continue;
                }

                switch (cha)
                {
                case '/':
                    if (this._blockComment && prev == '*')
                    {
                        this._blockComment = false;
                    }
                    if (!this._inString)
                    {
                        if (!this._blockComment && next == '/')
                        {
                            this._lineComment = true;
                        }
                        if (!this._lineComment && next == '*')
                        {
                            this._blockComment = true;
                        }
                    }
                    break;

                case '"':
                    if (!(this._lineComment || this._blockComment))
                    {
                        if (this._inString)
                        {
                            this._inString = !this._escape;
                        }
                    }
                    break;

                case '\\':
                    if (this._inString)
                    {
                        this._escape = true;
                    }
                    break;

                default:
                    break;
                }

                if (this._lineComment || this._blockComment || this._inString)
                {
                    if (this._wordBuilder.Length > 0)
                    {
                        this._block.LastLiteral = this._wordBuilder.ToString();
                    }
                    this._wordBuilder.Length = 0;
                    continue;
                }

                if (char.IsLetterOrDigit(cha))
                {
                    this._wordBuilder.Append(cha);
                }
                else
                {
                    if (this._wordBuilder.Length > 0)
                    {
                        this._block.LastLiteral = this._wordBuilder.ToString();
                    }
                    this._wordBuilder.Length = 0;
                }

                switch (cha)
                {
                case '(':
                case '{':
                case '[':
                    this._block.ResetOneLineBlock();
                    this._blocks.Push(this._block);
                    this._block.StartLine = document.LineNumber;
                    if (!indented)
                    {
                        this._block.Indent(settings);
                        indented = true;
                    }
                    this._block.Bracket = cha;
                    break;

                case ')':
                case '}':
                case ']':
                    var openBracket = StringChecker.GetOpenBracket(cha);
                    while (this._block.Bracket != openBracket)
                    {
                        if (this._blocks.Count == 0)
                        {
                            break;
                        }
                        this._block = this._blocks.Pop();
                    }
                    if (this._blocks.Count == 0)
                    {
                        break;
                    }
                    this._block = this._blocks.Pop();
                    this._block.Continuation = false;
                    this._block.ResetOneLineBlock();
                    break;
                }

                if (!char.IsWhiteSpace(cha))
                {
                    this._lastNonCommentChar = cha;
                }
            }

            if (this._wordBuilder.Length > 0)
            {
                this._block.LastLiteral = this._wordBuilder.ToString();
            }
            this._wordBuilder.Length = 0;

            if ((startInComment && line[0] != '*') ||
                document.Text.StartsWith("//\t", StringComparison.Ordinal) ||
                (document.Text == "//"))
            {
                return;
            }

            if ("]})".Contains(line[0]))
            {
                indent.Append(oldBlock.OuterIndent);
                oldBlock.ResetOneLineBlock();
                oldBlock.Continuation = false;
            }
            else
            {
                indent.Append(oldBlock.InnerIndent);
            }

            if (document.IsReadOnly)
            {
                if (!oldBlock.Continuation && oldBlock.OneLineBlock == 0 &&
                    oldBlock.StartLine == this._block.StartLine &&
                    this._block.StartLine < document.LineNumber && this._lastNonCommentChar != ':')
                {
                    indent.Length = 0;
                    line          = document.Text;
                    for (int i = 0; i < line.Length; ++i)
                    {
                        if (!char.IsWhiteSpace(line[i]))
                        {
                            break;
                        }
                        indent.Append(line[i]);
                    }

                    if (startInComment && indent.Length > 0 && indent[indent.Length - 1] == ' ')
                    {
                        indent.Length -= 1;
                    }
                    this._block.InnerIndent = indent.ToString();
                }
                return;
            }

            if (startInComment)
            {
                indent.Append(' ');
            }

            if (indent.Length != (document.Text.Length - line.Length) ||
                !document.Text.StartsWith(indent.ToString(), StringComparison.Ordinal) ||
                char.IsWhiteSpace(document.Text[indent.Length]))
            {
                document.Text = indent.ToString() + line;
            }
        }