@ui5/builder 4.0.4 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -2
- package/lib/processors/jsdoc/lib/createIndexFiles.js +58 -61
- package/lib/processors/jsdoc/lib/transformApiJson.js +343 -254
- package/lib/processors/jsdoc/lib/ui5/plugin.js +169 -123
- package/lib/processors/jsdoc/lib/ui5/template/publish.js +76 -447
- package/lib/processors/jsdoc/lib/ui5/template/utils/typeParser.js +489 -0
- package/lib/processors/jsdoc/lib/ui5/template/utils/versionUtil.js +6 -4
- package/package.json +6 -6
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
/* global env
|
|
9
|
-
/* eslint-env es6,node */
|
|
10
|
-
/* eslint strict: [2, "global"] */
|
|
8
|
+
/* global env */
|
|
11
9
|
|
|
12
10
|
"use strict";
|
|
13
11
|
|
|
@@ -27,6 +25,7 @@ const warning = logger.warn.bind(logger);
|
|
|
27
25
|
const error = logger.error.bind(logger);
|
|
28
26
|
|
|
29
27
|
const {extractVersion, extractSince} = require("./utils/versionUtil");
|
|
28
|
+
const {ASTBuilder, TypeParser} = require("./utils/typeParser");
|
|
30
29
|
|
|
31
30
|
/* errors that might fail the build in future */
|
|
32
31
|
function future(msg) {
|
|
@@ -42,39 +41,7 @@ function future(msg) {
|
|
|
42
41
|
/* globals, constants */
|
|
43
42
|
const MY_TEMPLATE_NAME = "ui5",
|
|
44
43
|
MY_ALT_TEMPLATE_NAME = "sapui5-jsdoc3",
|
|
45
|
-
ANONYMOUS_LONGNAME = doclet.ANONYMOUS_LONGNAME
|
|
46
|
-
A_SECURITY_TAGS = [
|
|
47
|
-
{
|
|
48
|
-
name : "SecSource",
|
|
49
|
-
caption : "Taint Source",
|
|
50
|
-
description : "APIs that might introduce tainted data into an application, e.g. due to user input or network access",
|
|
51
|
-
params : ["out","flags"]
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
name : "SecEntryPoint",
|
|
55
|
-
caption : "Taint Entry Point",
|
|
56
|
-
description: "APIs that are called implicitly by a framework or server and trigger execution of application logic",
|
|
57
|
-
params : ["in","flags"]
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name : "SecSink",
|
|
61
|
-
caption : "Taint Sink",
|
|
62
|
-
description : "APIs that pose a security risk when they receive tainted data",
|
|
63
|
-
params : ["in","flags"]
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
name : "SecPassthrough",
|
|
67
|
-
caption : "Taint Passthrough",
|
|
68
|
-
description : "APIs that might propagate tainted data when they receive it as input",
|
|
69
|
-
params : ["in","out","flags"]
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
name : "SecValidate",
|
|
73
|
-
caption : "Validation",
|
|
74
|
-
description : "APIs that (partially) cleanse tainted data so that it no longer poses a security risk in the further data flow of an application",
|
|
75
|
-
params : ["in","out","flags"]
|
|
76
|
-
}
|
|
77
|
-
];
|
|
44
|
+
ANONYMOUS_LONGNAME = doclet.ANONYMOUS_LONGNAME;
|
|
78
45
|
|
|
79
46
|
const templatesConf = (env.conf.templates || {}),
|
|
80
47
|
templateConf = templatesConf[MY_TEMPLATE_NAME] || templatesConf[MY_ALT_TEMPLATE_NAME] || {};
|
|
@@ -83,7 +50,7 @@ let conf = {};
|
|
|
83
50
|
|
|
84
51
|
let __symbols;
|
|
85
52
|
let __longnames;
|
|
86
|
-
|
|
53
|
+
const __missingLongnames = {};
|
|
87
54
|
|
|
88
55
|
function merge(target, source) {
|
|
89
56
|
if ( source != null ) {
|
|
@@ -119,7 +86,7 @@ function lookup(key) {
|
|
|
119
86
|
function createSymbol(longname, lines = []) {
|
|
120
87
|
const comment = [
|
|
121
88
|
"@name " + longname,
|
|
122
|
-
...
|
|
89
|
+
...lines
|
|
123
90
|
];
|
|
124
91
|
|
|
125
92
|
const symbol = new doclet.Doclet("/**\n * " + comment.join("\n * ") + "\n */", {});
|
|
@@ -215,7 +182,7 @@ function writeSymbols(symbols, filename, caption) {
|
|
|
215
182
|
v.base = value.base.longname;
|
|
216
183
|
}
|
|
217
184
|
if ( value.implementations ) {
|
|
218
|
-
v.base = value.implementations.map(($)=> $.longname);
|
|
185
|
+
v.base = value.implementations.map(($) => $.longname);
|
|
219
186
|
}
|
|
220
187
|
if ( value.parent ) {
|
|
221
188
|
v.parent = value.parent.longname;
|
|
@@ -454,7 +421,7 @@ function createInheritanceTree(allSymbols) {
|
|
|
454
421
|
} else {
|
|
455
422
|
warning(`create missing class ${sClass} (extended by ${sExtendingClass})`);
|
|
456
423
|
}
|
|
457
|
-
|
|
424
|
+
const oBaseClass = getOrCreateClass(sBaseClass, sClass);
|
|
458
425
|
oClass = createSymbol(sClass, [
|
|
459
426
|
"@extends " + sBaseClass,
|
|
460
427
|
"@" + sKind,
|
|
@@ -485,7 +452,7 @@ function createInheritanceTree(allSymbols) {
|
|
|
485
452
|
aRootTypes.push(oClass);
|
|
486
453
|
}
|
|
487
454
|
|
|
488
|
-
|
|
455
|
+
const oBaseClass = getOrCreateClass(sBaseClass, oClass.longname);
|
|
489
456
|
oClass.__ui5.base = oBaseClass;
|
|
490
457
|
oBaseClass.__ui5.derived = oBaseClass.__ui5.derived || [];
|
|
491
458
|
oBaseClass.__ui5.derived.push(oClass);
|
|
@@ -667,60 +634,8 @@ function sortByAlias(a, b) {
|
|
|
667
634
|
return 0;
|
|
668
635
|
}
|
|
669
636
|
|
|
670
|
-
/* Make a symbol sorter by some attribute. */
|
|
671
|
-
function makeSortby(/* fields ...*/) {
|
|
672
|
-
const aFields = Array.prototype.slice.apply(arguments),
|
|
673
|
-
aNorms = [],
|
|
674
|
-
aFuncs = [];
|
|
675
|
-
for (let i = 0; i < arguments.length; i++) {
|
|
676
|
-
aNorms[i] = 1;
|
|
677
|
-
if ( typeof aFields[i] === 'function' ) {
|
|
678
|
-
aFuncs[i] = aFields[i];
|
|
679
|
-
continue;
|
|
680
|
-
}
|
|
681
|
-
aFuncs[i] = function($,n) { return $[n]; };
|
|
682
|
-
if ( aFields[i].indexOf("!") === 0 ) {
|
|
683
|
-
aNorms[i] = -1;
|
|
684
|
-
aFields[i] = aFields[i].slice(1);
|
|
685
|
-
}
|
|
686
|
-
if ( aFields[i] === 'deprecated' ) {
|
|
687
|
-
aFuncs[i] = function($,n) { return !!$[n]; };
|
|
688
|
-
} else if ( aFields[i] === 'static' ) {
|
|
689
|
-
aFields[i] = 'scope';
|
|
690
|
-
aFuncs[i] = function($,n) { return $[n] === 'static'; };
|
|
691
|
-
} else if ( aFields[i].indexOf("#") === 0 ) {
|
|
692
|
-
aFields[i] = aFields[i].slice(1);
|
|
693
|
-
aFuncs[i] = function($,n) { return $.comment.getTag(n).length > 0; };
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
return function(a, b) {
|
|
697
|
-
// debug(`compare ${a.longname} : ${b.longname}`);
|
|
698
|
-
let r = 0;
|
|
699
|
-
for (let i = 0; r === 0 && i < aFields.length; i++) {
|
|
700
|
-
let va = aFuncs[i](a,aFields[i]);
|
|
701
|
-
let vb = aFuncs[i](b,aFields[i]);
|
|
702
|
-
if ( va && !vb ) {
|
|
703
|
-
r = -aNorms[i];
|
|
704
|
-
} else if ( !va && vb ) {
|
|
705
|
-
r = aNorms[i];
|
|
706
|
-
} else if ( va && vb ) {
|
|
707
|
-
va = String(va).toLowerCase();
|
|
708
|
-
vb = String(vb).toLowerCase();
|
|
709
|
-
if (va < vb) {
|
|
710
|
-
r = -aNorms[i];
|
|
711
|
-
}
|
|
712
|
-
if (va > vb) {
|
|
713
|
-
r = aNorms[i];
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
// debug(` ${aFields[i]}: ${va} ? ${vb} = ${r}`);
|
|
717
|
-
}
|
|
718
|
-
return r;
|
|
719
|
-
};
|
|
720
|
-
}
|
|
721
|
-
|
|
722
637
|
function getMembersOfKind(data, kind) {
|
|
723
|
-
|
|
638
|
+
const oResult = [];
|
|
724
639
|
//debug(`calculating kind ${kind} from ${data.longname}`);
|
|
725
640
|
//console.log(data);
|
|
726
641
|
let fnFilter;
|
|
@@ -759,94 +674,6 @@ function getMembersOfKind(data, kind) {
|
|
|
759
674
|
|
|
760
675
|
// ---- type parsing ---------------------------------------------------------------------------------------------
|
|
761
676
|
|
|
762
|
-
class ASTBuilder {
|
|
763
|
-
literal(str) {
|
|
764
|
-
return {
|
|
765
|
-
type: "literal",
|
|
766
|
-
value: str
|
|
767
|
-
};
|
|
768
|
-
}
|
|
769
|
-
simpleType(type) {
|
|
770
|
-
return {
|
|
771
|
-
type: "simpleType",
|
|
772
|
-
name: type
|
|
773
|
-
};
|
|
774
|
-
}
|
|
775
|
-
array(componentType) {
|
|
776
|
-
return {
|
|
777
|
-
type: "array",
|
|
778
|
-
component: componentType
|
|
779
|
-
};
|
|
780
|
-
}
|
|
781
|
-
object(keyType, valueType) {
|
|
782
|
-
return {
|
|
783
|
-
type: "object",
|
|
784
|
-
key: keyType,
|
|
785
|
-
value: valueType
|
|
786
|
-
};
|
|
787
|
-
}
|
|
788
|
-
set(elementType) {
|
|
789
|
-
return {
|
|
790
|
-
type: "set",
|
|
791
|
-
element: elementType
|
|
792
|
-
};
|
|
793
|
-
}
|
|
794
|
-
promise(fulfillmentType) {
|
|
795
|
-
return {
|
|
796
|
-
type: "promise",
|
|
797
|
-
fulfill: fulfillmentType
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
"function"(paramTypes, returnType, thisType, constructorType) {
|
|
801
|
-
return {
|
|
802
|
-
"type": "function",
|
|
803
|
-
"params": paramTypes,
|
|
804
|
-
"return": returnType,
|
|
805
|
-
"this": thisType,
|
|
806
|
-
"constructor": constructorType
|
|
807
|
-
};
|
|
808
|
-
}
|
|
809
|
-
structure(structure) {
|
|
810
|
-
return {
|
|
811
|
-
type: "structure",
|
|
812
|
-
fields: structure
|
|
813
|
-
};
|
|
814
|
-
}
|
|
815
|
-
union(types) {
|
|
816
|
-
return {
|
|
817
|
-
type: "union",
|
|
818
|
-
types: types
|
|
819
|
-
};
|
|
820
|
-
}
|
|
821
|
-
synthetic(type) {
|
|
822
|
-
type.synthetic = true;
|
|
823
|
-
return type;
|
|
824
|
-
}
|
|
825
|
-
nullable(type) {
|
|
826
|
-
type.nullable = true;
|
|
827
|
-
return type;
|
|
828
|
-
}
|
|
829
|
-
mandatory(type) {
|
|
830
|
-
type.mandatory = true;
|
|
831
|
-
return type;
|
|
832
|
-
}
|
|
833
|
-
optional(type) {
|
|
834
|
-
type.optional = true;
|
|
835
|
-
return type;
|
|
836
|
-
}
|
|
837
|
-
repeatable(type) {
|
|
838
|
-
type.repeatable = true;
|
|
839
|
-
return type;
|
|
840
|
-
}
|
|
841
|
-
typeApplication(type, templateTypes) {
|
|
842
|
-
return {
|
|
843
|
-
type: "typeApplication",
|
|
844
|
-
baseType: type,
|
|
845
|
-
templateTypes: templateTypes
|
|
846
|
-
};
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
|
|
850
677
|
class TypeStringBuilder {
|
|
851
678
|
constructor() {
|
|
852
679
|
this.lt = "<";
|
|
@@ -906,7 +733,7 @@ class TypeStringBuilder {
|
|
|
906
733
|
"function"(paramTypes, returnType) {
|
|
907
734
|
return {
|
|
908
735
|
simpleComponent: false,
|
|
909
|
-
str: "function(" + paramTypes.map(type => type.str).join(',') + ")" + ( returnType ? " : " + this.safe(returnType) : "")
|
|
736
|
+
str: "function(" + paramTypes.map((type) => type.str).join(',') + ")" + ( returnType ? " : " + this.safe(returnType) : "")
|
|
910
737
|
};
|
|
911
738
|
}
|
|
912
739
|
structure(structure) {
|
|
@@ -934,7 +761,7 @@ class TypeStringBuilder {
|
|
|
934
761
|
union(types) {
|
|
935
762
|
return {
|
|
936
763
|
needsParenthesis: true,
|
|
937
|
-
str: types.map(type => this.safe(type)).join('|')
|
|
764
|
+
str: types.map((type) => this.safe(type)).join('|')
|
|
938
765
|
};
|
|
939
766
|
}
|
|
940
767
|
synthetic(type) {
|
|
@@ -960,248 +787,11 @@ class TypeStringBuilder {
|
|
|
960
787
|
typeApplication(type, templateTypes) {
|
|
961
788
|
return {
|
|
962
789
|
simpleComponent: false,
|
|
963
|
-
str: this.safe(type) + this.lt + templateTypes.map(type => this.safe(type)).join(',') + this.gt
|
|
790
|
+
str: this.safe(type) + this.lt + templateTypes.map((type) => this.safe(type)).join(',') + this.gt
|
|
964
791
|
};
|
|
965
792
|
}
|
|
966
793
|
}
|
|
967
794
|
|
|
968
|
-
function TypeParser(defaultBuilder = new ASTBuilder()) {
|
|
969
|
-
const rLexer = /\s*(Array\.?<|Object\.?<|Set\.?<|Promise\.?<|function\(|\{|:|\(|\||\}|\.?<|>|\)|,|\[\]|\*|\?|!|=|\.\.\.)|\s*(false|true|(?:\+|-)?(?:\d+(?:\.\d+)?|NaN|Infinity)|'[^']*'|"[^"]*"|null|undefined)|\s*((?:module:)?\w+(?:[/.#~][$\w_]+)*)|./g;
|
|
970
|
-
|
|
971
|
-
let input;
|
|
972
|
-
let builder;
|
|
973
|
-
let token;
|
|
974
|
-
let tokenStr;
|
|
975
|
-
|
|
976
|
-
function next(expected) {
|
|
977
|
-
if ( expected !== undefined && token !== expected ) {
|
|
978
|
-
throw new SyntaxError(
|
|
979
|
-
`TypeParser: expected '${expected}', but found '${tokenStr}' ` +
|
|
980
|
-
`(pos: ${rLexer.lastIndex}, input='${input}')`
|
|
981
|
-
);
|
|
982
|
-
}
|
|
983
|
-
const match = rLexer.exec(input);
|
|
984
|
-
if ( match ) {
|
|
985
|
-
tokenStr = match[1] || match[2] || match[3];
|
|
986
|
-
token = match[1] || (match[2] && "literal") || (match[3] && "symbol");
|
|
987
|
-
if ( !token ) {
|
|
988
|
-
throw new SyntaxError(`TypeParser: unexpected '${match[0]}' (pos: ${match.index}, input='${input}')`);
|
|
989
|
-
}
|
|
990
|
-
} else {
|
|
991
|
-
tokenStr = token = null;
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
function parseType() {
|
|
996
|
-
let nullable = false;
|
|
997
|
-
let mandatory = false;
|
|
998
|
-
if ( token === "?" ) {
|
|
999
|
-
next();
|
|
1000
|
-
nullable = true;
|
|
1001
|
-
} else if ( token === "!" ) {
|
|
1002
|
-
next();
|
|
1003
|
-
mandatory = true;
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
let type;
|
|
1007
|
-
|
|
1008
|
-
if ( token === "literal" ) {
|
|
1009
|
-
type = builder.literal(tokenStr);
|
|
1010
|
-
next();
|
|
1011
|
-
} else if ( token === "Array.<" || token === "Array<" ) {
|
|
1012
|
-
next();
|
|
1013
|
-
const componentType = parseTypes();
|
|
1014
|
-
next(">");
|
|
1015
|
-
type = builder.array(componentType);
|
|
1016
|
-
} else if ( token === "Object.<" || token === "Object<" ) {
|
|
1017
|
-
next();
|
|
1018
|
-
let keyType;
|
|
1019
|
-
let valueType = parseTypes();
|
|
1020
|
-
if ( token === "," ) {
|
|
1021
|
-
next();
|
|
1022
|
-
keyType = valueType;
|
|
1023
|
-
valueType = parseTypes();
|
|
1024
|
-
} else {
|
|
1025
|
-
keyType = builder.synthetic(builder.simpleType("string"));
|
|
1026
|
-
}
|
|
1027
|
-
next(">");
|
|
1028
|
-
type = builder.object(keyType, valueType);
|
|
1029
|
-
} else if ( token === "Set.<" || token === "Set<" ) {
|
|
1030
|
-
next();
|
|
1031
|
-
const elementType = parseTypes();
|
|
1032
|
-
next(">");
|
|
1033
|
-
type = builder.set(elementType);
|
|
1034
|
-
} else if ( token === "Promise.<" || token === "Promise<" ) {
|
|
1035
|
-
next();
|
|
1036
|
-
const resultType = parseTypes();
|
|
1037
|
-
next(">");
|
|
1038
|
-
type = builder.promise(resultType);
|
|
1039
|
-
} else if ( token === "function(" ) {
|
|
1040
|
-
next();
|
|
1041
|
-
let thisType;
|
|
1042
|
-
let constructorType;
|
|
1043
|
-
const paramTypes = [];
|
|
1044
|
-
let returnType;
|
|
1045
|
-
if ( tokenStr === "this" ) {
|
|
1046
|
-
next();
|
|
1047
|
-
next(":");
|
|
1048
|
-
thisType = parseType();
|
|
1049
|
-
if ( token !== ")" ) {
|
|
1050
|
-
next(",");
|
|
1051
|
-
}
|
|
1052
|
-
} else if ( tokenStr === "new" ) {
|
|
1053
|
-
next();
|
|
1054
|
-
next(":");
|
|
1055
|
-
constructorType = parseType();
|
|
1056
|
-
if ( token !== ")" ) {
|
|
1057
|
-
next(",");
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
while ( token !== ")" ) {
|
|
1061
|
-
const repeatable = token === "...";
|
|
1062
|
-
if ( repeatable ) {
|
|
1063
|
-
next();
|
|
1064
|
-
}
|
|
1065
|
-
let paramType = parseTypes();
|
|
1066
|
-
if ( repeatable ) {
|
|
1067
|
-
paramType = builder.repeatable(paramType);
|
|
1068
|
-
}
|
|
1069
|
-
const optional = token === "=";
|
|
1070
|
-
if ( optional ) {
|
|
1071
|
-
paramType = builder.optional(paramType);
|
|
1072
|
-
next();
|
|
1073
|
-
}
|
|
1074
|
-
paramTypes.push(paramType);
|
|
1075
|
-
|
|
1076
|
-
// exit if there are no more parameters
|
|
1077
|
-
if ( token !== "," ) {
|
|
1078
|
-
break;
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
if ( repeatable ) {
|
|
1082
|
-
throw new SyntaxError(
|
|
1083
|
-
`TypeParser: only the last parameter of a function can be repeatable ` +
|
|
1084
|
-
`(pos: ${rLexer.lastIndex}, input='${input}')`
|
|
1085
|
-
);
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
// consume the comma
|
|
1089
|
-
next();
|
|
1090
|
-
}
|
|
1091
|
-
next(")");
|
|
1092
|
-
if ( token === ":" ) {
|
|
1093
|
-
next(":");
|
|
1094
|
-
returnType = parseType();
|
|
1095
|
-
}
|
|
1096
|
-
type = builder.function(paramTypes, returnType, thisType, constructorType);
|
|
1097
|
-
} else if ( token === "{" ) {
|
|
1098
|
-
const structure = Object.create(null);
|
|
1099
|
-
next();
|
|
1100
|
-
do {
|
|
1101
|
-
const propName = tokenStr;
|
|
1102
|
-
if ( !/^\w+$/.test(propName) ) {
|
|
1103
|
-
throw new SyntaxError(
|
|
1104
|
-
`TypeParser: structure field must have a simple name ` +
|
|
1105
|
-
`(pos: ${rLexer.lastIndex}, input='${input}', field:'${propName}')`
|
|
1106
|
-
);
|
|
1107
|
-
}
|
|
1108
|
-
next("symbol");
|
|
1109
|
-
let propType;
|
|
1110
|
-
const optional = token === "=";
|
|
1111
|
-
if ( optional ) {
|
|
1112
|
-
next();
|
|
1113
|
-
}
|
|
1114
|
-
if ( token === ":" ) {
|
|
1115
|
-
next();
|
|
1116
|
-
propType = parseTypes();
|
|
1117
|
-
} else {
|
|
1118
|
-
propType = builder.synthetic(builder.simpleType("any"));
|
|
1119
|
-
}
|
|
1120
|
-
if ( optional ) {
|
|
1121
|
-
propType = builder.optional(propType);
|
|
1122
|
-
}
|
|
1123
|
-
structure[propName] = propType;
|
|
1124
|
-
if ( token === "}" ) {
|
|
1125
|
-
break;
|
|
1126
|
-
}
|
|
1127
|
-
next(",");
|
|
1128
|
-
} while (token);
|
|
1129
|
-
next("}");
|
|
1130
|
-
type = builder.structure(structure);
|
|
1131
|
-
} else if ( token === "(" ) {
|
|
1132
|
-
next();
|
|
1133
|
-
type = parseTypes();
|
|
1134
|
-
next(")");
|
|
1135
|
-
} else if ( token === "*" ) {
|
|
1136
|
-
next();
|
|
1137
|
-
type = builder.simpleType("*");
|
|
1138
|
-
} else {
|
|
1139
|
-
type = builder.simpleType(tokenStr);
|
|
1140
|
-
next("symbol");
|
|
1141
|
-
// check for suffix operators: either 'type application' (generics) or 'array', but not both of them
|
|
1142
|
-
if ( token === "<" || token === ".<" ) {
|
|
1143
|
-
next();
|
|
1144
|
-
const templateTypes = [];
|
|
1145
|
-
do {
|
|
1146
|
-
const templateType = parseTypes();
|
|
1147
|
-
templateTypes.push(templateType);
|
|
1148
|
-
if ( token === ">" ) {
|
|
1149
|
-
break;
|
|
1150
|
-
}
|
|
1151
|
-
next(",");
|
|
1152
|
-
} while (token);
|
|
1153
|
-
next(">");
|
|
1154
|
-
type = builder.typeApplication(type, templateTypes);
|
|
1155
|
-
} else {
|
|
1156
|
-
while ( token === "[]" ) {
|
|
1157
|
-
next();
|
|
1158
|
-
type = builder.array(type);
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
if ( builder.normalizeType ) {
|
|
1163
|
-
type = builder.normalizeType(type);
|
|
1164
|
-
}
|
|
1165
|
-
if ( nullable ) {
|
|
1166
|
-
type = builder.nullable(type);
|
|
1167
|
-
}
|
|
1168
|
-
if ( mandatory ) {
|
|
1169
|
-
type = builder.mandatory(type);
|
|
1170
|
-
}
|
|
1171
|
-
return type;
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
function parseTypes() {
|
|
1175
|
-
const types = [];
|
|
1176
|
-
do {
|
|
1177
|
-
types.push(parseType());
|
|
1178
|
-
if ( token !== "|" ) {
|
|
1179
|
-
break;
|
|
1180
|
-
}
|
|
1181
|
-
next();
|
|
1182
|
-
} while (token);
|
|
1183
|
-
return types.length === 1 ? types[0] : builder.union(types);
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
this.parse = function(typeStr, tempBuilder = defaultBuilder) {
|
|
1187
|
-
/*
|
|
1188
|
-
try {
|
|
1189
|
-
const r = catharsis.parse(typeStr, { jsdoc: true});
|
|
1190
|
-
console.log(JSON.stringify(typeStr, null, "\t"), r);
|
|
1191
|
-
} catch (err) {
|
|
1192
|
-
console.log(typeStr, err);
|
|
1193
|
-
}
|
|
1194
|
-
*/
|
|
1195
|
-
builder = tempBuilder;
|
|
1196
|
-
input = String(typeStr);
|
|
1197
|
-
rLexer.lastIndex = 0;
|
|
1198
|
-
next();
|
|
1199
|
-
const type = parseTypes();
|
|
1200
|
-
next(null);
|
|
1201
|
-
return type;
|
|
1202
|
-
};
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
795
|
const typeParser = new TypeParser();
|
|
1206
796
|
const _TEXT_BUILDER = new TypeStringBuilder();
|
|
1207
797
|
|
|
@@ -1235,6 +825,7 @@ function _processTypeString(type, builder) {
|
|
|
1235
825
|
return type;
|
|
1236
826
|
}
|
|
1237
827
|
}
|
|
828
|
+
return undefined;
|
|
1238
829
|
}
|
|
1239
830
|
|
|
1240
831
|
function listTypes(type) {
|
|
@@ -1341,13 +932,13 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1341
932
|
const obj = [];
|
|
1342
933
|
let curr = obj;
|
|
1343
934
|
let attribForKind = 'kind';
|
|
1344
|
-
|
|
935
|
+
const stack = [];
|
|
1345
936
|
|
|
1346
937
|
function isEmpty(obj) {
|
|
1347
938
|
if ( !obj ) {
|
|
1348
939
|
return true;
|
|
1349
940
|
}
|
|
1350
|
-
for (
|
|
941
|
+
for (const n in obj) {
|
|
1351
942
|
if ( obj.hasOwnProperty(n) ) {
|
|
1352
943
|
return false;
|
|
1353
944
|
}
|
|
@@ -1448,7 +1039,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1448
1039
|
}
|
|
1449
1040
|
if (info.since === null) {
|
|
1450
1041
|
future(`**** Failed to parse version in string '${value}'. ` +
|
|
1451
|
-
`Version might be missing or has an unexpected format.`)
|
|
1042
|
+
`Version might be missing or has an unexpected format.`);
|
|
1452
1043
|
}
|
|
1453
1044
|
if ( info.value ) {
|
|
1454
1045
|
curr["text"] = normalizeWS(info.value);
|
|
@@ -1513,7 +1104,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1513
1104
|
if ( $.access === 'restricted' ) {
|
|
1514
1105
|
return $.__ui5.stakeholders;
|
|
1515
1106
|
}
|
|
1516
|
-
|
|
1107
|
+
return undefined;
|
|
1517
1108
|
}
|
|
1518
1109
|
|
|
1519
1110
|
function exceptions(symbol) {
|
|
@@ -1604,7 +1195,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1604
1195
|
|
|
1605
1196
|
if ( metadata.specialSettings && Object.keys(metadata.specialSettings).length > 0 ) {
|
|
1606
1197
|
collection("specialSettings");
|
|
1607
|
-
for (
|
|
1198
|
+
for ( const n in metadata.specialSettings ) {
|
|
1608
1199
|
const special = metadata.specialSettings[n];
|
|
1609
1200
|
tag("specialSetting");
|
|
1610
1201
|
attrib("name", special.name);
|
|
@@ -1625,7 +1216,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1625
1216
|
|
|
1626
1217
|
if ( metadata.properties && Object.keys(metadata.properties).length > 0 ) {
|
|
1627
1218
|
collection("properties");
|
|
1628
|
-
for (
|
|
1219
|
+
for ( const n in metadata.properties ) {
|
|
1629
1220
|
const prop = metadata.properties[n];
|
|
1630
1221
|
let defaultValue = prop.defaultValue != null ? prop.defaultValue.value : null;
|
|
1631
1222
|
// JSON can't transport a value of undefined, so represent it as string
|
|
@@ -1670,7 +1261,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1670
1261
|
|
|
1671
1262
|
if ( metadata.aggregations && Object.keys(metadata.aggregations).length > 0 ) {
|
|
1672
1263
|
collection("aggregations");
|
|
1673
|
-
for (
|
|
1264
|
+
for ( const n in metadata.aggregations ) {
|
|
1674
1265
|
const aggr = metadata.aggregations[n];
|
|
1675
1266
|
tag("aggregation");
|
|
1676
1267
|
attrib("name", aggr.name);
|
|
@@ -1707,7 +1298,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1707
1298
|
|
|
1708
1299
|
if ( metadata.associations && Object.keys(metadata.associations).length > 0 ) {
|
|
1709
1300
|
collection("associations");
|
|
1710
|
-
for (
|
|
1301
|
+
for ( const n in metadata.associations ) {
|
|
1711
1302
|
const assoc = metadata.associations[n];
|
|
1712
1303
|
tag("association");
|
|
1713
1304
|
attrib("name", assoc.name);
|
|
@@ -1731,7 +1322,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1731
1322
|
|
|
1732
1323
|
if ( metadata.events && Object.keys(metadata.events).length > 0 ) {
|
|
1733
1324
|
collection("events");
|
|
1734
|
-
for (
|
|
1325
|
+
for ( const n in metadata.events ) {
|
|
1735
1326
|
const event = metadata.events[n];
|
|
1736
1327
|
tag("event");
|
|
1737
1328
|
attrib("name", event.name);
|
|
@@ -1751,7 +1342,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1751
1342
|
tagWithSince("deprecated", event.deprecation);
|
|
1752
1343
|
if ( event.parameters && Object.keys(event.parameters).length > 0 ) {
|
|
1753
1344
|
tag("parameters");
|
|
1754
|
-
for (
|
|
1345
|
+
for ( const pn in event.parameters ) {
|
|
1755
1346
|
if ( event.parameters.hasOwnProperty(pn) ) {
|
|
1756
1347
|
const param = event.parameters[pn];
|
|
1757
1348
|
tag(pn);
|
|
@@ -1774,7 +1365,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
1774
1365
|
|
|
1775
1366
|
if ( metadata.annotations && Object.keys(metadata.annotations).length > 0 ) {
|
|
1776
1367
|
collection("annotations");
|
|
1777
|
-
for (
|
|
1368
|
+
for ( const n in metadata.annotations ) {
|
|
1778
1369
|
const anno = metadata.annotations[n];
|
|
1779
1370
|
tag("annotation");
|
|
1780
1371
|
attrib("name", anno.name);
|
|
@@ -2308,7 +1899,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
2308
1899
|
if ( symbol.__ui5.stereotype !== 'xmlmacro' && ownMethods.length > 0 ) {
|
|
2309
1900
|
collection("methods");
|
|
2310
1901
|
ownMethods.forEach(function(member) {
|
|
2311
|
-
writeMethod(member, undefined, symbol.kind === 'interface' ||
|
|
1902
|
+
writeMethod(member, undefined, symbol.kind === 'interface' || symbol.kind === 'class');
|
|
2312
1903
|
if ( member.__ui5.members ) {
|
|
2313
1904
|
// HACK: export nested static functions as siblings of the current function
|
|
2314
1905
|
// A correct representation has to be discussed with the SDK / WebIDE
|
|
@@ -2377,7 +1968,7 @@ function postProcessAPIJSON(api) {
|
|
|
2377
1968
|
function guessExports(moduleName, symbols) {
|
|
2378
1969
|
|
|
2379
1970
|
// a non-stringifiable special value for unresolved exports
|
|
2380
|
-
|
|
1971
|
+
const UNRESOLVED = function() {};
|
|
2381
1972
|
|
|
2382
1973
|
symbols = symbols.sort((a,b) => {
|
|
2383
1974
|
if ( a.name === b.name ) {
|
|
@@ -2457,7 +2048,7 @@ function postProcessAPIJSON(api) {
|
|
|
2457
2048
|
|
|
2458
2049
|
}
|
|
2459
2050
|
|
|
2460
|
-
for (
|
|
2051
|
+
for ( const n in modules ) {
|
|
2461
2052
|
guessExports(n, modules[n]);
|
|
2462
2053
|
}
|
|
2463
2054
|
|
|
@@ -2478,7 +2069,7 @@ function postProcessAPIJSON(api) {
|
|
|
2478
2069
|
}
|
|
2479
2070
|
symbol = findSymbol(symbol.extends);
|
|
2480
2071
|
}
|
|
2481
|
-
|
|
2072
|
+
return undefined;
|
|
2482
2073
|
}
|
|
2483
2074
|
|
|
2484
2075
|
// See sap/ui/base/ManagedObjectMetadata
|
|
@@ -2525,6 +2116,37 @@ function postProcessAPIJSON(api) {
|
|
|
2525
2116
|
`doesn't match containing library '${api.library}'. Library must be explicitly defined in class metadata!`);
|
|
2526
2117
|
}
|
|
2527
2118
|
}
|
|
2119
|
+
if (Array.isArray(symbol["ui5-metadata"].properties)) {
|
|
2120
|
+
for (const prop of symbol["ui5-metadata"].properties) {
|
|
2121
|
+
let moduleType;
|
|
2122
|
+
// cut off array brackets for symbol lookup
|
|
2123
|
+
const arrType = isArrayType(prop.type);
|
|
2124
|
+
let lookupType = prop.type;
|
|
2125
|
+
if (arrType) {
|
|
2126
|
+
lookupType = lookupType.replace("[]", "");
|
|
2127
|
+
}
|
|
2128
|
+
if (prop.dataType === undefined
|
|
2129
|
+
&& findSymbol(lookupType) == null
|
|
2130
|
+
&& !lookupType?.startsWith("module:")
|
|
2131
|
+
&& findSymbol(moduleType = `module:${lookupType.replace(/\./g, "/")}`) != null) {
|
|
2132
|
+
// note: the dataType must be the original, including array brackets if present
|
|
2133
|
+
prop.dataType = prop.type;
|
|
2134
|
+
// the moduleType also needs to include the array brackets if present in the original dataType
|
|
2135
|
+
prop.type = moduleType + (arrType ? "[]" : "");
|
|
2136
|
+
for (const methodName of prop.methods) {
|
|
2137
|
+
const method = symbol.methods?.find((m) => m.name === methodName);
|
|
2138
|
+
if (methodName.startsWith("get")
|
|
2139
|
+
&& method?.returnValue?.type === prop.dataType) {
|
|
2140
|
+
method.returnValue.type = prop.type;
|
|
2141
|
+
} else if (methodName.startsWith("set")
|
|
2142
|
+
&& method?.parameters?.[0]?.type === prop.dataType) {
|
|
2143
|
+
method.parameters[0].type = prop.type;
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
info(`${symbol.name}: adapted type of ${prop.name} and its accessors from '${prop.dataType}' to '${prop.type}'`);
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2528
2150
|
});
|
|
2529
2151
|
|
|
2530
2152
|
}
|
|
@@ -2568,16 +2190,22 @@ const builtinTypes = {
|
|
|
2568
2190
|
Attr:true,
|
|
2569
2191
|
Blob:true,
|
|
2570
2192
|
DataTransfer:true,
|
|
2193
|
+
DragEvent:true,
|
|
2571
2194
|
Document:true,
|
|
2572
2195
|
DOMException:true,
|
|
2196
|
+
DOMRect:true,
|
|
2573
2197
|
Element:true,
|
|
2574
2198
|
Event:true,
|
|
2575
2199
|
File:true,
|
|
2576
2200
|
FileList:true,
|
|
2201
|
+
FormData:true,
|
|
2577
2202
|
Headers:true,
|
|
2578
2203
|
HTMLDocument:true,
|
|
2579
2204
|
HTMLElement:true,
|
|
2580
2205
|
Node:true,
|
|
2206
|
+
PerformanceResourceTiming:true,
|
|
2207
|
+
Request:true,
|
|
2208
|
+
Response:true,
|
|
2581
2209
|
Storage:true,
|
|
2582
2210
|
Touch:true,
|
|
2583
2211
|
TouchList:true,
|
|
@@ -2628,7 +2256,9 @@ function validateAPIJSON(api) {
|
|
|
2628
2256
|
// create map of defined symbols (built-in types, dependency libraries, current library)
|
|
2629
2257
|
const defined = Object.assign(Object.create(null), builtinTypes, externalSymbols);
|
|
2630
2258
|
if ( api.symbols ) {
|
|
2631
|
-
api.symbols.forEach((symbol) =>
|
|
2259
|
+
api.symbols.forEach((symbol) => {
|
|
2260
|
+
defined[symbol.name] = symbol;
|
|
2261
|
+
});
|
|
2632
2262
|
}
|
|
2633
2263
|
|
|
2634
2264
|
const naming = Object.create(null);
|
|
@@ -2783,12 +2413,10 @@ function validateAPIJSON(api) {
|
|
|
2783
2413
|
if ( !intfParam.optional ) {
|
|
2784
2414
|
reportError(oIntfAPI.name, `parameter ${intfParam.name} missing in implementation of ${symbol.name}#${intfMethod.name}`);
|
|
2785
2415
|
}
|
|
2786
|
-
} else {
|
|
2787
|
-
|
|
2788
|
-
reportError(oIntfAPI.name, `type of parameter ${intfParam.name} of interface method differs from type in implementation ${symbol.name}#${intfMethod.name}`);
|
|
2789
|
-
}
|
|
2790
|
-
// TODO check nested properties
|
|
2416
|
+
} else if ( implParam.type !== intfParam.type ) {
|
|
2417
|
+
reportError(oIntfAPI.name, `type of parameter ${intfParam.name} of interface method differs from type in implementation ${symbol.name}#${intfMethod.name}`);
|
|
2791
2418
|
}
|
|
2419
|
+
// TODO check nested properties
|
|
2792
2420
|
});
|
|
2793
2421
|
}
|
|
2794
2422
|
if ( intfMethod.returnValue != null && implMethod.returnValue == null ) {
|
|
@@ -2830,7 +2458,7 @@ function validateAPIJSON(api) {
|
|
|
2830
2458
|
if ( symbol.implements ) {
|
|
2831
2459
|
symbol.implements.forEach((intf) => {
|
|
2832
2460
|
checkSimpleType(intf, `interface of ${symbol.name}`);
|
|
2833
|
-
|
|
2461
|
+
const oIntfAPI = defined[intf];
|
|
2834
2462
|
if ( oIntfAPI ) {
|
|
2835
2463
|
checkClassAgainstInterface(symbol, oIntfAPI);
|
|
2836
2464
|
}
|
|
@@ -3085,6 +2713,7 @@ function createAPIXML(symbols, filename, options = {}) {
|
|
|
3085
2713
|
*/
|
|
3086
2714
|
function toRaw(value, type) {
|
|
3087
2715
|
if ( typeof value === "string" && !isEnum(type) ) {
|
|
2716
|
+
// eslint-disable-next-line no-control-regex
|
|
3088
2717
|
return "\"" + value.replace(/[\u0000-\u001f"\\]/g,
|
|
3089
2718
|
(c) => replacement[c] || "\\u" + c.charCodeAt(0).toString(16).padStart(4, "0")) + "\"";
|
|
3090
2719
|
}
|
|
@@ -3229,7 +2858,7 @@ function createAPIXML(symbols, filename, options = {}) {
|
|
|
3229
2858
|
tagWithSince("deprecated", event.deprecated);
|
|
3230
2859
|
if ( event.parameters ) {
|
|
3231
2860
|
tag("parameters");
|
|
3232
|
-
for (
|
|
2861
|
+
for ( const pn in event.parameters ) {
|
|
3233
2862
|
if ( event.parameters.hasOwnProperty(pn) ) {
|
|
3234
2863
|
const param = event.parameters[pn];
|
|
3235
2864
|
|
|
@@ -3374,7 +3003,7 @@ function createAPIXML(symbols, filename, options = {}) {
|
|
|
3374
3003
|
let count = 0;
|
|
3375
3004
|
|
|
3376
3005
|
if ( props ) {
|
|
3377
|
-
for (
|
|
3006
|
+
for (const n in props ) {
|
|
3378
3007
|
if ( props.hasOwnProperty(n) ) {
|
|
3379
3008
|
|
|
3380
3009
|
param = props[n];
|
|
@@ -3526,7 +3155,7 @@ function createAPIXML(symbols, filename, options = {}) {
|
|
|
3526
3155
|
}
|
|
3527
3156
|
|
|
3528
3157
|
if ( !legacyContent ) {
|
|
3529
|
-
if ( hasSettings && j
|
|
3158
|
+
if ( hasSettings && j === 1 && /setting/i.test(param.name) && /object/i.test(param.type) ) {
|
|
3530
3159
|
if ( addRedundancy ) {
|
|
3531
3160
|
tag("parameterProperties");
|
|
3532
3161
|
writeParameterPropertiesForMSettings(symbolAPI);
|