Skip to content

Commit

Permalink
Java
Browse files Browse the repository at this point in the history
  • Loading branch information
astreet committed Oct 7, 2014
1 parent 7eef01f commit 6d93c20
Show file tree
Hide file tree
Showing 33 changed files with 5,457 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
a.out
*.class
/**/java/out/*
/**/.idea/workspace.xml
19 changes: 15 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@

FILES=src/__tests__/Layout-test.c src/Layout.c src/Layout-test-utils.c

all: c test
all: c c_test java java_test

c:
@node ./src/transpile.js
c: transpile_all

test:
c_test: c
@gcc -std=c99 -Werror -Wno-padded $(FILES) -lm && ./a.out
@rm a.out

java: transpile_all src/java
@javac -cp ./lib/junit4.jar -sourcepath ./src/java/src:./src/java/tests src/java/tests/com/facebook/csslayout/*.java

java_test: java
@java -cp ./src/java/src:./src/java/tests:./lib/junit4.jar org.junit.runner.JUnitCore \
com.facebook.csslayout.LayoutEngineTest \
com.facebook.csslayout.LayoutCachingTest \
com.facebook.csslayout.CSSNodeTest

transpile_all: ./src/transpile.js
@node ./src/transpile.js

debug:
@gcc -ggdb $(FILES) -lm && lldb ./a.out
@rm a.out
Binary file added lib/junit4.jar
Binary file not shown.
110 changes: 110 additions & 0 deletions src/JavaTranspiler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
function __transpileToJavaCommon(code) {
return code
.replace(/CSS_UNDEFINED/g, 'CSSConstants.UNDEFINED')
.replace(/css_flex_direction_t/g, 'CSSFlexDirection')
.replace(/CSS_FLEX_DIRECTION_/g, 'CSSFlexDirection.')
.replace(/css_align_t/g, 'CSSAlign')
.replace(/CSS_ALIGN_/g, 'CSSAlign.')
.replace(/CSS_POSITION_/g, 'CSSPositionType.')
.replace(/css_justify_t/g, 'CSSJustify')
.replace(/CSS_JUSTIFY_/g, 'CSSJustify.')
.replace(/css_dim_t/g, 'MeasureOutput')
.replace(/bool/g, 'boolean')
.replace(/^(\s+)([^\s]+)\s+\+=/gm, '$1$2 = $2 +') // Expand +=
.replace(/leading\[([^\]]+)\]/g, 'getLeading($1)')
.replace(/trailing\[([^\]]+)\]/g, 'getTrailing($1)')
.replace(/pos\[([^\]]+)\]/g, 'getPos($1)')
.replace(/dim\[([^\]]+)\]/g, 'getDim($1)')
.replace(/isUndefined/g, 'FloatUtil.isUndefined')

// Since Java doesn't store its attributes in arrays, we need to use setters/getters to access
// the appropriate layout/style fields
.replace(
/(\w+)\.layout\[((?:getLeading|getPos)\([^\)]+\))\]\s+=\s+([^;]+);/gm,
'setLayoutPosition($1, $2, $3);')
.replace(/(\w+)\.layout\[((?:getLeading|getPos)\([^\]]+\))\]/g, 'getLayoutPosition($1, $2)')
.replace(
/(\w+)\.layout\[(getDim\([^\)]+\))\]\s+=\s+([^;]+);/gm,
'setLayoutDimension($1, $2, $3);')
.replace(/(\w+)\.layout\[(getDim\([^\]]+\))\]/g, 'getLayoutDimension($1, $2)')
.replace(/(\w+)\.style\[((?:getLeading|getPos)\([^\]]+\))\]/g, 'getStylePosition($1, $2)')
.replace(/(\w+)\.style\[(getDim\([^\]]+\))\]/g, 'getStyleDimension($1, $2)');
}

function __transpileSingleTestToJava(code) {
return __transpileToJavaCommon(code)
.replace(/new_test_css_node/g, 'new TestCSSNode')
.replace( // style.dimensions[CSS_WIDTH] => style.width
/(style|layout)\.dimensions\[CSS_(WIDTH|HEIGHT)\]/g,
function (str, match1, match2) {
return match1 + '.' + match2.toLowerCase();
})
.replace( // layout.position[CSS_TOP] => layout.y
/layout\.position\[CSS_(TOP|LEFT)\]/g,
function (str, match1) {
return 'layout.' + (match1 == 'TOP' ? 'y' : 'x');
})
.replace( // style.position[CSS_TOP] => style.positionTop
/style\.(position|margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g,
function (str, match1, match2) {
return 'style.' + match1 + match2[0] + match2.substring(1).toLowerCase();
})
.replace(/get_child\(.*context\,\s([^\)]+)\)/g, 'getChildAt($1)')
.replace(/init_css_node_children/g, 'addChildren')
.replace(/css_node_t(\s)\*/g, 'TestCSSNode$1')
.replace(/\->/g, '.')
.replace(/(\d+\.\d+)/g, '$1f')
.replace( // style.flex_direction => style.flexDirection
/style\.([^_\s]+)_(\w)(\w+)/g,
function (str, match1, match2, match3) {
return 'style.' + match1 + match2.toUpperCase() + match3;
})
.replace(/(\w+)\.measure\s+=\s+.+/, '$1.setMeasureFunction(sTestMeasureFunction);');
}

function indent(code) {
return code
.split('\n')
.map(function(line) { return ' ' + line; })
.join('\n');
}

var JavaTranspiler = {
transpileLayoutEngine: function(code) {
return indent(
__transpileToJavaCommon(code)
.replace(/function\s+layoutNode.*/, '')
.replace('node.style.measure', 'node.measure')
.replace(/\.children\.length/g, '.getChildCount()')
.replace(/node.children\[i\]/g, 'node.getChildAt(i)')
.replace(/fmaxf/g, 'Math.max')
.replace(/\/\*\([^\/]+\*\/\n/g, '') // remove comments for other languages
.replace(/var\/\*([^\/]+)\*\//g, '$1')
.replace(/ === /g, ' == ')
.replace(/\n /g, '\n')
.replace(/\/[*]!([^*]+)[*]\//g, '$1')
.replace(/css_node_t\*/g, 'CSSNode'));
},

transpileCConstDefs: function(cConstDefs) {
return indent(
cConstDefs
.replace(/#define\s+(\w+)\s+(\"[^\"]+\")/g, 'public static final String $1 = $2;')
.replace(/#define\s+(\w+)\s+(.+)/g, 'public static final float $1 = $2f;'));
},

transpileCTestsArray: function(allTestsInC) {
var allTestsInJava = [];
for (var i = 0; i < allTestsInC.length; i++) {
allTestsInJava[i] =
" @Test\n" +
" public void testCase" + i + "()\n" +
__transpileSingleTestToJava(allTestsInC[i]);
}
return allTestsInJava.join('\n\n');
},
}

if (typeof module !== 'undefined') {
module.exports = JavaTranspiler;
}
8 changes: 4 additions & 4 deletions src/Layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
// Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both
// left and right or top and bottom).
for (int ii = 0; ii < 2; ii++) {
css_flex_direction_t axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (!isUndefined(node->layout.dimensions[dim[axis]]) &&
!isDimDefined(child, axis) &&
isPosDefined(child, leading[axis]) &&
Expand Down Expand Up @@ -491,7 +491,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {

// If there are flexible children in the mix, they are going to fill the
// remaining space
if (flexibleChildrenCount) {
if (flexibleChildrenCount != 0) {
float flexibleMainDim = remainingMainDim / totalFlexible;

// The non flexible children can overflow the container, in this case
Expand Down Expand Up @@ -675,7 +675,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
// Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both
// left and right or top and bottom).
for (int ii = 0; ii < 2; ii++) {
css_flex_direction_t axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (!isUndefined(node->layout.dimensions[dim[axis]]) &&
!isDimDefined(child, axis) &&
isPosDefined(child, leading[axis]) &&
Expand All @@ -692,7 +692,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
}
}
for (int ii = 0; ii < 2; ii++) {
css_flex_direction_t axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (isPosDefined(child, trailing[axis]) &&
!isPosDefined(child, leading[axis])) {
child->layout.position[leading[axis]] =
Expand Down
10 changes: 5 additions & 5 deletions src/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ var computeLayout = (function() {
// Let's not measure the text if we already know both dimensions
if (isRowUndefined || isColumnUndefined) {
var/*css_dim_t*/ measure_dim = node.style.measure(
/*!node->context,*/
/*(c)!node->context,*/
width
);
if (isRowUndefined) {
Expand Down Expand Up @@ -273,7 +273,7 @@ var computeLayout = (function() {
// Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both
// left and right or top and bottom).
for (var/*int*/ ii = 0; ii < 2; ii++) {
var/*css_flex_direction_t*/ axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
var/*css_flex_direction_t*/ axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (!isUndefined(node.layout[dim[axis]]) &&
!isDimDefined(child, axis) &&
isPosDefined(child, leading[axis]) &&
Expand Down Expand Up @@ -366,7 +366,7 @@ var computeLayout = (function() {

// If there are flexible children in the mix, they are going to fill the
// remaining space
if (flexibleChildrenCount) {
if (flexibleChildrenCount != 0) {
var/*float*/ flexibleMainDim = remainingMainDim / totalFlexible;

// The non flexible children can overflow the container, in this case
Expand Down Expand Up @@ -550,7 +550,7 @@ var computeLayout = (function() {
// Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both
// left and right or top and bottom).
for (var/*int*/ ii = 0; ii < 2; ii++) {
var/*css_flex_direction_t*/ axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
var/*css_flex_direction_t*/ axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (!isUndefined(node.layout[dim[axis]]) &&
!isDimDefined(child, axis) &&
isPosDefined(child, leading[axis]) &&
Expand All @@ -567,7 +567,7 @@ var computeLayout = (function() {
}
}
for (var/*int*/ ii = 0; ii < 2; ii++) {
var/*css_flex_direction_t*/ axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
var/*css_flex_direction_t*/ axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (isPosDefined(child, trailing[axis]) &&
!isPosDefined(child, leading[axis])) {
child.layout[leading[axis]] =
Expand Down
1 change: 1 addition & 0 deletions src/java/.idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions src/java/.idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/java/.idea/copyright/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/java/.idea/encodings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/java/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/java/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/java/.idea/scopes/scope_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6d93c20

Please sign in to comment.