Giter Site home page Giter Site logo

icarus-consulting / yaapii.xambly Goto Github PK

View Code? Open in Web Editor NEW
7.0 4.0 0.0 3.92 MB

A port of Xembly library by Yegor Bugayenko. Lighweight XML parser, generator and manipulator.

License: MIT License

C# 96.65% PowerShell 3.35%
xml xmlparser intermediate-language printer oop yaapii xembly

yaapii.xambly's Introduction

Build status codecov

Yaapii.Xambly

Port of Xembly Library from Yegor Bugayenko.

The following usage guide is taken from the original repository.

Repo Guidelines

Main responsible for this repository is HerickJ-22. Please request in every single PR a review from him.

Usage

Xambly is an Assembly-like imperative programming language for data manipulation in XML documents. It is a much simplier alternative to XSLT and XQuery. Read this blog post for a more detailed explanation: Xembly, an Assembly for XML.

Here is a command line implementation (as Ruby gem): Xembly-gem

For example, you have an XML document:

<orders>
  <order id="553">
    <amount>$45.00</amount>
  </order>
</orders>

And you want to change the amount of the order #553 from $45.00 to $140.00. Xambly script would look like:

XPATH "orders/order[@id=553]";
SET "$140.00";

It is much simpler and compact than XSLT or XQuery.

Directives

Full list of supported directives in the current version:

  • ADD: adds new node to all current nodes
  • ADDIF: adds new node, if it's absent
  • ADDIFATTRIBUTE: adds new node, if a child element with specified attribute does not exist
  • ADDIFCHILD: adds new node, if a child element with specified content as text does not exist
  • ATTR: adds a attribute to the current node, with name and value
  • CDATA: same as SET, but makes CDATA
  • INSERTAFTER: adds new node after the current node
  • INSERTBEFORE: adds new node before the current node
  • NS: sets namespace of all current nodes
  • PI: adds processing instruction
  • POP: retrieves cursor from stack
  • PUSH: saves cursor in stack
  • REMOVE: removes all current nodes
  • SET: sets text value of current node
  • STRICT: throws an exception if cursor is missing nodes
  • UP: moves cursor one node up
  • XPATH: moves cursor to the nodes found by XPath
  • XSET: sets text value, calculating it with XPath

"Cursor" or "current nodes" is where we're currently located in the XML document. When Xambly script starts, the cursor is empty and simply points to the highest level in the XML hierarchy. Pay attention, it doesn't point to the root node. It points to one level above the root. Remember, when document is empty, there is no root.

Then, we start executing directives one by one. After each directive cursor is moving somewhere. There may be many nodes under the cursor, or just one, or none. For example, let's assume we're starting with this simple document <car/>:

ADD 'hello';        // nothing happens, since cursor is empty
XPATH '/car';       // there is one node <car> under the cursor
ADD 'make';         // the result is "<car><make/></car>",
                    // cursor has one node "<make/>"
ATTR 'name', 'BMW'; // the result is "<car><make name='BMW'/></car>"
                    // cursor still has one node "<make/>"
UP;                 // cursor has one node "<car>"
ADD 'mileage';      // the result is "<car><make name='BMW'/><mileage/></car>"
                    // cursor still has one node "<car>"
XPATH '*';          // cursor has two nodes "<make name='BMW'/>"
                    // and "<mileage/>"
REMOVE;             // the result is "<car/>", since all nodes under
                    // the cursor are removed

You can create a collection of directives either from text or via supplementary methods, one per each directive. In both cases, you need to use class Directives:

import org.Xambly.Directives;
new Directives("XPATH '//car'; REMOVE;");
new Directives().xpath("//car").remove();

The second option is preferable, because it is faster - there is no parsing involved.

ADD

ADD directive adds a new node to every node in the current node set. ADD expects exactly one mandatory argument, which is the name of a new node to be added (case sensitive):

ADD 'orders';
ADD 'order';

Even if the node with the same name already exists, a new node will be added. Use ADDIF if you need to add only if the same-name node is absent.

After execution, ADD directive moves the cursor to the nodes just added.

ADDIF

ADDIF directive adds a new node to every node of the current set, only if it's absent. ADDIF expects exactly one argument, which is the name of the node to be added (case sensitive):

ADD 'orders';
ADDIF 'order';

After execution, ADDIF directive moves the cursor to the nodes just added.

SET

SET changes text content of all current nodes, and expects exactly one argument, which is the text content to set:

ADD "employee";
SET "John Smith";

SET doesn't move the cursor anywhere.

XSET

XSET changes text content of all current nodes to a value calculated with XPath expression:

ADD "product-1";
ADD "price";
XSET "sum(/products/price) div count(/products)";

XSET doesn't move the cursor anywhere.

UP

UP moves all current nodes to their parents.

XPATH

XPATH changes current nodes to the all found by XPath expression:

XPATH "//employee[@id='234' and name='John Smith']/name";
SET "John R. Smith";

REMOVE

REMOVE removes current nodes under the cursor and moves the cursor to their parents:

ADD "employee";
REMOVE;

STRICT

STRICT checks that there is certain number of current nodes:

XPATH "//employee[name='John Doe']";  // move cursor to the employee
STRICT "1";                           // throw an exception if there
                                      // is not exactly one node under
                                      // the cursor

This is a very effective mechanism of validation of your script, in production mode. It is similar to assert statement in Java. It is recommended to use STRICT regularly, to make sure your cursor has correct amount of nodes, to avoid unexpected modifications.

STRICT doesn't move the cursor anywhere.

PI

PI directive add a new processing directive to the XML:

PI "xsl-stylesheet" "href='http://example.com'";

PI doesn't move the cursor anywhere.

PUSH and POP

PUSH and POP directives saves current DOM position to stack and restores it from there.

Let's say you start your Xambly manipulations from a place in DOM, which location is not determined for you. After your manipulations are done, you want to get back to exactly the same place. You should use PUSH to save your current location and POP to restore it back, when manipulations are finished, for example:

PUSH;                        // doesn't matter where we are
                             // we just save the location to stack
XPATH '//user[@id="123"]';   // move the cursor to a completely
                             // different location in the XML
ADD 'name';                  // add "<name/>" to all nodes under the cursor
SET 'Jeff';                  // set text value to the nodes
POP;                         // get back to where we were before the PUSH

PUSH basically saves the cursor into stack and POP restores it from there. This is a very similar technique to PUSH/POP directives in Assembly. The stack has no limits, you can push multiple times and pop them back. It is a stack, that's why it is First-In-Last-Out (FILO).

This operation is fast and it is highly recommended to use it everywhere, to be sure you're not making unexpected changes to the XML document. Every time you're not sure where your

NS

NS adds a namespace attribute to a node:

XPATH '/garage/car';                // move cursor to "<car/>" node(s)
NS "http://www.w3.org/TR/html4/";   // set namespace there

If original document was like this:

<garage>
  <car>BMW</car>
  <car>Toyota</car>
</garage>

After applying that two directives it will look like this:

<garage xmlns:a="http://www.w3.org/TR/html4/">
  <a:car>BMW</a:car>
  <a:car>Toyota</a:car>
</garage>

The namspace prefix may no necessarily be a:, but it doesn't really matter.

NS doesn't move the cursor anywhere.

XML Collections

Let's say you want to build an XML document with a collection of names:

package org.Xambly.example;
import org.Xambly.Directives;
import org.Xambly.Xambler;
public class XamblyExample {
  public static void main(String[] args) throws Exception {
    String[] names = new String[] {
      "Jeffrey Lebowski",
      "Walter Sobchak",
      "Theodore Donald 'Donny' Kerabatsos",
    };
    Directives directives = new Directives().add("actors");
    for (String name : names) {
      directives.add("actor").set(name).up();
    }
    System.out.println(new Xambler(directives).xml());
  }
}

Standard output will contain this text:

<?xml version="1.0" encoding="UTF-8"?>
<actors>
  <actor>Jeffrey Lebowski</actor>
  <actor>Walter Sobchak</actor>
  <actor>Theodore Donald &apos;Donny&apos; Kerabatsos</actor>
</actors>

Merging Documents

When you need to add an entire XML document, you can convert it first into Xambly directives and then add them all together:

Iterable<Iterable> dirs = new Directives()
  .add("garage")
  .append(Directives.copyOf(node))
  .add("something-else");

This static utility method copyOf() converts an instance of class org.w3c.dom.Node into a collection of Xambly directives. Then, method append() adds them all together to the main list.

Unfortunately, not every valid XML document can be parsed by copyOf(). For example, this one will lead to a runtime exception: <car>2015<name>BMW</name></car>. Read more about Xambly limitations, a few paragraphs below.

Escaping Invalid XML Text

XML, as standard, doesn't allow certain characters in its body. For example, this code will throw an exception:

String xml = new Xambler(
  new Directives().add("car").set("\u00")
).xml();

Character \u00 is not allowed in XML. Actually, these ranges are not allowed: \u00..\u08, \u0B..\u0C, \u0E..\u1F, \u7F..\u84, and \u86..u9F.

This means that you should validate everything and make sure you're setting only "valid" text values to XML nodes. Sometimes, it's not feasible to always check them. Sometimes you may simply need to save whatever is possible and call it a day. There a utility static method Xambler.escape(), to help you do that:

String xml = new Xambler(
  new Directives().add("car").set(Xambler.escape("\u00"))
).xml();

This code won't throw an exception. Method Xambler.escape() will conver "\u00" to "\u0000". It is recommended to use this method everywhere, if you are not sure about the quality of the content.

Shaded Xambly JAR With Dependencies

Usually, you're supposed to use this dependency in your pom.xml:

<dependency>
  <groupId>com.jcabi.incubator</groupId>
  <artifactId>Xambly</artifactId>
</dependency>

However, if you have conflicts between dependencies, you can use our "shaded" JAR, that includes all dependencies:

<dependency>
  <groupId>com.jcabi.incubator</groupId>
  <artifactId>Xambly</artifactId>
  <classifier>jar-with-dependencies</classifier>
</dependency>

Known Limitations

Xambly is not intended to be a replacement of XSL or XQuery. It is a lightweight (!) instrument for XML manipulations. There are a few things that can't be done by means of Xambly:

  • You can't add, remove, or modify XML comments (but you can find them with XPath)

  • DTD section can't be modified

  • Elements and text content can't be mixed, e.g. this structure is not supported: <test>hello <b>friend</a></test>

Some of these limitations may be removed in the next versions.

How To Contribute

Fork repository, make changes, send us a pull request. We will review your changes and apply them to the master branch shortly, provided they don't violate our quality standards. To avoid frustration, before sending us your pull request, please run full build from powershell:

.\build.ps1

yaapii.xambly's People

Contributors

avexcaesar avatar edjopato avatar fneu avatar herickj-22 avatar icacle avatar icaobu avatar koeeenig avatar meerownymous avatar mse1188 avatar pz1337 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

yaapii.xambly's Issues

Directives.Strict(): Remove NotImplementedException and implement the Code

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

The code works as its designed

Actual Behavior

https://github.com/icarus-consulting/Yaapii.Xembly/blob/b59b9e11f0ed1edc3a0953a12fe293dcb8ca8f6f/src/Yaapii.Xml.Xembly/Directive/Directives.cs#L486-L491

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

This Issue Depends on issue #14

Comment XmlDocumentOf

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Comments like in PR #49

Actual Behavior

No comments.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Remove build warnings

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

No warnings when compiling.

Actual Behavior

Still warnings:

Severity	Code	Description	Project	File	Line	Suppression State
Warning	CS3021	'XemblyBaseListener' does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute	Yaapii.Xml.Xembly	C:\Users\csa\Source\Git\Yaapii.Xembly\src\Yaapii.Xml.Xembly\Antlr4\XemblyBaseListener.cs	44	Active
Warning	CS3021	'XemblyLexer' does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute	Yaapii.Xml.Xembly	C:\Users\csa\Source\Git\Yaapii.Xembly\src\Yaapii.Xml.Xembly\Antlr4\XemblyLexer.cs	40	Active
Warning	CS3021	'IXemblyListener' does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute	Yaapii.Xml.Xembly	C:\Users\csa\Source\Git\Yaapii.Xembly\src\Yaapii.Xml.Xembly\Antlr4\XemblyListener.cs	40	Active
Warning	CS3021	'XemblyParser' does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute	Yaapii.Xml.Xembly	C:\Users\csa\Source\Git\Yaapii.Xembly\src\Yaapii.Xml.Xembly\Antlr4\XemblyParser.cs	43	Active
Warning	CS0162	Unreachable code detected	Yaapii.Xml.Xembly	C:\Users\csa\Source\Git\Yaapii.Xembly\src\Yaapii.Xml.Xembly\Directive\Directives.cs	431	Active
Warning	CS0162	Unreachable code detected	Yaapii.Xml.Xembly	C:\Users\csa\Source\Git\Yaapii.Xembly\src\Yaapii.Xml.Xembly\Directive\Directives.cs	490	Active
Warning	CS0168	The variable 'ex' is declared but never used	Yaapii.Xml.Xembly	C:\Users\csa\Source\Git\Yaapii.Xembly\src\Yaapii.Xml.Xembly\Xembler.cs	127	Active
Warning	CS0168	The variable 'ex' is declared but never used	Yaapii.Xml.Xembly	C:\Users\csa\Source\Git\Yaapii.Xembly\src\Yaapii.Xml.Xembly\Xembler.cs	132	Active

Steps to reproduce the behavior

Build

The log given by the failure.

Mention any other details that might be useful

Migrate to Atoms 0.5.8

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Project references Atoms 0.5.8

Actual Behavior

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

AddDirective ignores namespace

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Directive considers xml namespaces

Actual Behavior

namespaces are ignored

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

AddDirective fails on XmlDocument

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Add directives to a given XmlDocument

Actual Behavior

Throws Yaapii.Xml.Xembly.ImpossibleModificationException

Steps to reproduce the behavior

var doc = new XmlDocument();
new Xembler(
    new EnumerableOf<IDirective>(
                new AddDirective("root")
             )
    ).Apply(doc);

The log given by the failure.

Yaapii.Xml.Xembly.ImpossibleModificationException: 'Exception at dir 1: Yaapii.Xml.Xembly.AddDirective'

Mention any other details that might be useful

In the AddDirective The XmlNode dom element is null at OwnerDocument if it is of type XmlDocument.. There fore a new XmlDocument is created as dom element. https://github.com/icarus-consulting/Yaapii.Xembly/blob/b44eae162e96205f6733a47a48bcf91a21caa187/src/Yaapii.Xml.Xembly/Directive/AddDirective.cs#L30-L34

If is pass in a XmlNode into the Apply-Method everything works fine.

Migrate to Atoms 0.5.9

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Xembly uses Atoms 0.5.9

Actual Behavior

It uses 0.5.8

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Make Directives accept Atoms IText

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Directives accept IText

Actual Behavior

Directives accepts only string

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Directives.Xset(): Remove NotImplementedException and implement the Code

This Issue depends on issue #20

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

The code works as its designed

Actual Behavior

https://github.com/icarus-consulting/Yaapii.Xembly/blob/b59b9e11f0ed1edc3a0953a12fe293dcb8ca8f6f/src/Yaapii.Xml.Xembly/Directive/Directives.cs#L428-L445

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Make a pre build event which trigger ANTLR4 compiling

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

When I change the xembly.g file which is an ANTLR4 source file, the ANTLR4 compiler is triggered and my C# classes are being updated.

Actual Behavior

I have to trigger the compilation manually.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

To trigger the compiler, navigate into project root and call from commandline:
java -jar tools/antlr-4.7-complete.jar -Dlanguage=CSharp .\src\Yaapii.Xml.Xembly\Antlr4\Xembly.g

Java 1.8 is needed.

new class XmlDocumentOf

I Modified AddDirective.

I created a class for retrieving XmlDocument from Node which encapsulates your solution. But I realized that we appearantly do not need the else if, because the msdn says:

Wenn der Knoten ein XmlDocument ist (NodeType ist gleich XmlNodeType.Document), gibt diese Eigenschaft null zurück.

Agreed @koeeenig ?

Add missing MIT License header and missing comments

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Add MIT License in all files:

// MIT License
//
// Copyright(c) 2017 ICARUS Consulting GmbH
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

And add missing comments in some files.

Actual Behavior

Missing License and missing comments.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Integrate third party library to use XPath 2.0. or 3.0

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

We have XPath 2.0 or 3.0

Actual Behavior

Microsoft C# only supports XPath 1.0

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

  • Saxon: XPath 3.1, XQuery 3.1, XSLT 3.0
  • XmlPrime: XPath 3.1, XQuery 3.1, XSLT 2.0
  • QueryMachine: XPath 2.0, XQuery 1.0
  • Lightweight XPath2 for .NET: XPath 2.0
  • Exselt: XSLT 3.0

Unittest for XPathDirective

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

We have a unittest.

Actual Behavior

No Unittest.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Add an Directive to add comments

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

There is an Directive e.g. AddComment() to add comments

Actual Behavior

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Downgrade to antlr 4.6 for usage in Tecnomatix

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Actual Behavior

Tecnomatix uses .Net 4.6.1 which cannot use ANTLR 4.7.

Steps to reproduce the behavior

Xembly uses ANTLR 4.6 which is available for .Net 4.6.1.

The log given by the failure.

Mention any other details that might be useful

AppVeyor: Not generating ANTLR4 files

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

ANTLR4 files are generated, the AppVeyor executes the PreBuild event whic is defined in Yaapii.Xml.Xembly.csproj

Actual Behavior

Parser files are not generated. They are included manually now.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

  • Maybe the PreBuild event is not triggered by DotNetCoreBuild in cake (simulate this locally?)
  • Maybe the Environment variable for Java is not coreectly set, so that we have to adjust our PreBuild event

Correct Test Namespaces

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Most Tests have the namespace Yaapii.Xml.Xembly.Tests.Directive
some have the namespace Yaapii.Xml.Xembly.Directive.Tests

I think to remeber we said the last one should be used, right?

Actual Behavior

Mixed namespace

Steps to reproduce the behavior

https://github.com/icarus-consulting/Yaapii.Xembly/blob/f0350ac1312451c27f32b0814cb2a713fba01bf1/tests/Yaapii.Xml.Xembly.Tests/Directive/DirectivesTest.cs#L14

https://github.com/icarus-consulting/Yaapii.Xembly/blob/f0350ac1312451c27f32b0814cb2a713fba01bf1/tests/Yaapii.Xml.Xembly.Tests/Directive/PopDirectiveTests.cs#L8

The log given by the failure.

Mention any other details that might be useful

Add Cake Build script

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Cake Build script exists.
Steps are:

  • Clean
  • Restore
  • Build
  • Test
  • Pack
  • Release

Actual Behavior

No build script for Build server exists

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

The build script is similar to icarus-consulting/Yaapii.Deployment

Unittest for Popdirective

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

We have a unittest.

Actual Behavior

No Unittest.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Unittest for Pushdirective

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

We have a unittest.

Actual Behavior

No Unittest.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Make ANTL4 Parser work

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

ANTL4 Parser is ready but not integrated.

Actual Behavior

ANTL4 Parser works

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Unittest for Directives

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

We have a unittest.

Actual Behavior

No Unittest.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Must Xembler.Apply() be threadsafe?

We can modify directives and Apply() is not affected.

Is this possible?

Another solution could be that we use the (yet not existing) copyof method, which then should be threadsafe.

But lets discuss, if this is needed or not.

Comment SynchronizedCollection

Bug Report or Feature Request (mark with an x)

  • bug report -> please search issues before submitting
  • feature request

Expected Behavior

Comments like in PR #49

Actual Behavior

No comments.

Steps to reproduce the behavior

The log given by the failure.

Mention any other details that might be useful

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.