use of org.wso2.ballerinalang.compiler.semantics.analyzer.Types in project ballerina by ballerina-lang.
the class Generator method createDocForNode.
/**
* Create documentation for actions.
* @param actionNode ballerina action node.
* @return documentation for actions.
*/
public static ActionDoc createDocForNode(BLangAction actionNode) {
String actionName = actionNode.getName().value;
List<Variable> parameters = new ArrayList<>();
List<Variable> returnParams = new ArrayList<>();
// Iterate through the parameters
if (actionNode.getParameters().size() > 0) {
for (BLangVariable param : actionNode.getParameters()) {
String dataType = type(param);
String desc = paramAnnotation(actionNode, param);
Variable variable = new Variable(param.getName().value, dataType, desc);
parameters.add(variable);
}
}
// Iterate through the return types
if (actionNode.getReturnParameters().size() > 0) {
for (int i = 0; i < actionNode.getReturnParameters().size(); i++) {
BLangVariable returnParam = actionNode.getReturnParameters().get(i);
String dataType = type(returnParam);
String desc = returnParamAnnotation(actionNode, i);
Variable variable = new Variable(returnParam.getName().value, dataType, desc);
returnParams.add(variable);
}
}
return new ActionDoc(actionName, description(actionNode), new ArrayList<>(), parameters, returnParams);
}
use of org.wso2.ballerinalang.compiler.semantics.analyzer.Types in project ballerina by ballerina-lang.
the class Generator method generatePageForPrimitives.
/**
* Generate the page for primitive types.
* @param balPackage The ballerina.builtin package.
* @param packages List of available packages.
* @return A page model for the primitive types.
*/
public static Page generatePageForPrimitives(BLangPackage balPackage, List<Link> packages) {
ArrayList<Documentable> primitiveTypes = new ArrayList<>();
// Check for functions in the package
if (balPackage.getFunctions().size() > 0) {
for (BLangFunction function : balPackage.getFunctions()) {
if (function.getFlags().contains(Flag.PUBLIC) && function.getReceiver() != null) {
TypeNode langType = function.getReceiver().getTypeNode();
if (!(langType instanceof BLangUserDefinedType)) {
// Check for primitives in ballerina.builtin
Optional<PrimitiveTypeDoc> existingPrimitiveType = primitiveTypes.stream().filter((doc) -> doc instanceof PrimitiveTypeDoc && (((PrimitiveTypeDoc) doc)).name.equals(langType.toString())).map(doc -> (PrimitiveTypeDoc) doc).findFirst();
PrimitiveTypeDoc primitiveTypeDoc;
if (existingPrimitiveType.isPresent()) {
primitiveTypeDoc = existingPrimitiveType.get();
} else {
primitiveTypeDoc = new PrimitiveTypeDoc(langType.toString(), new ArrayList<>());
primitiveTypes.add(primitiveTypeDoc);
}
primitiveTypeDoc.children.add(createDocForNode(function));
}
}
}
}
// Create the links to select which page or package is active
List<Link> links = new ArrayList<>();
for (Link pkgLink : packages) {
if (BallerinaDocConstants.PRIMITIVE_TYPES_PAGE_NAME.equals(pkgLink.caption.value)) {
links.add(new Link(pkgLink.caption, pkgLink.href, true));
} else {
links.add(new Link(pkgLink.caption, pkgLink.href, false));
}
}
StaticCaption primitivesPageHeading = new StaticCaption(BallerinaDocConstants.PRIMITIVE_TYPES_PAGE_NAME);
return new Page(primitivesPageHeading, primitiveTypes, links);
}
use of org.wso2.ballerinalang.compiler.semantics.analyzer.Types in project ballerina by ballerina-lang.
the class BallerinaDocGenerator method generateApiDocs.
/**
* API to generate Ballerina API documentation.
*
* @param output path to the output directory where the API documentation will be written to.
* @param packageFilter comma separated list of package names to be filtered from the documentation.
* @param isNative whether the given packages are native or not.
* @param sources either the path to the directories where Ballerina source files reside or a
* path to a Ballerina file which does not belong to a package.
*/
public static void generateApiDocs(String output, String packageFilter, boolean isNative, String... sources) {
out.println("docerina: API documentation generation for sources - " + Arrays.toString(sources));
for (String source : sources) {
source = source.trim();
try {
Map<String, BLangPackage> docsMap;
if (source.endsWith(".bal")) {
Path sourceFilePath = Paths.get(source);
Path parentDir = sourceFilePath.getParent();
Path fileName = sourceFilePath.getFileName();
if (fileName == null) {
log.warn("Skipping the source generation for invalid path: " + sourceFilePath);
continue;
}
if (parentDir == null) {
parentDir = Paths.get(".");
}
docsMap = generatePackageDocsFromBallerina(parentDir.toString(), fileName, packageFilter, isNative);
} else {
Path dirPath = Paths.get(source);
// TODO fix this properly
// TODO Temporary fix that creates .ballerina to create project structure
Path projectFolder = dirPath.resolve(ProjectDirConstants.DOT_BALLERINA_DIR_NAME);
Files.createDirectory(projectFolder);
Path sourceRootPath = LauncherUtils.getSourceRootPath(dirPath.toString());
docsMap = generatePackageDocsFromBallerina(sourceRootPath.toString(), dirPath, packageFilter, isNative);
}
if (docsMap.size() == 0) {
out.println("docerina: no package definitions found!");
return;
}
if (BallerinaDocUtils.isDebugEnabled()) {
out.println("Generating HTML API documentation...");
}
String userDir = System.getProperty("user.dir");
// If output directory is empty
if (output == null) {
output = System.getProperty(BallerinaDocConstants.HTML_OUTPUT_PATH_KEY, userDir + File.separator + "api-docs" + File.separator + "html");
}
// Create output directories
Files.createDirectories(Paths.get(output));
// Sort packages by package path
List<BLangPackage> packageList = new ArrayList<>(docsMap.values());
packageList.sort(Comparator.comparing(pkg -> pkg.packageID.toString()));
// Iterate over the packages to generate the pages
List<String> packageNames = new ArrayList<>(docsMap.keySet());
// Sort the package names
Collections.sort(packageNames);
List<Link> packageNameList = PackageName.convertList(packageNames);
if (packageNames.contains("ballerina.builtin")) {
StaticCaption primitivesLinkName = new StaticCaption(BallerinaDocConstants.PRIMITIVE_TYPES_PAGE_NAME);
packageNameList.add(0, new Link(primitivesLinkName, BallerinaDocConstants.PRIMITIVE_TYPES_PAGE_HREF, false));
}
// Generate pages for the packages
String packageTemplateName = System.getProperty(BallerinaDocConstants.PACKAGE_TEMPLATE_NAME_KEY, "page");
for (BLangPackage bLangPackage : packageList) {
// Sort functions, connectors, structs, type mappers and annotationDefs
bLangPackage.getFunctions().sort(Comparator.comparing(f -> (f.getReceiver() == null ? "" : f.getReceiver().getName()) + f.getName().getValue()));
bLangPackage.getConnectors().sort(Comparator.comparing(c -> c.getName().getValue()));
bLangPackage.getStructs().sort(Comparator.comparing(s -> s.getName().getValue()));
bLangPackage.getAnnotations().sort(Comparator.comparing(a -> a.getName().getValue()));
bLangPackage.getEnums().sort(Comparator.comparing(a -> a.getName().getValue()));
// Sort connector actions
if ((bLangPackage.getConnectors() != null) && (bLangPackage.getConnectors().size() > 0)) {
bLangPackage.getConnectors().forEach(connector -> connector.getActions().sort(Comparator.comparing(a -> a.getName().getValue())));
}
String packagePath = refinePackagePath(bLangPackage);
Page page = Generator.generatePage(bLangPackage, packageNameList);
String filePath = output + File.separator + packagePath + HTML;
Writer.writeHtmlDocument(page, packageTemplateName, filePath);
if ("ballerina.builtin".equals(packagePath)) {
Page primitivesPage = Generator.generatePageForPrimitives(bLangPackage, packageNameList);
String primitivesFilePath = output + File.separator + "primitive-types" + HTML;
Writer.writeHtmlDocument(primitivesPage, packageTemplateName, primitivesFilePath);
}
}
// Generate the index file with the list of all packages
String indexTemplateName = System.getProperty(BallerinaDocConstants.PACKAGE_TEMPLATE_NAME_KEY, "index");
String indexFilePath = output + File.separator + "index" + HTML;
Writer.writeHtmlDocument(packageNameList, indexTemplateName, indexFilePath);
if (BallerinaDocUtils.isDebugEnabled()) {
out.println("Copying HTML theme...");
}
BallerinaDocUtils.copyResources("docerina-theme", output);
} catch (IOException e) {
out.println(String.format("docerina: API documentation generation failed for %s: %s", source, e.getMessage()));
log.error(String.format("API documentation generation failed for %s", source), e);
}
}
try {
String zipPath = System.getProperty(BallerinaDocConstants.OUTPUT_ZIP_PATH);
if (zipPath != null) {
BallerinaDocUtils.packageToZipFile(output, zipPath);
}
} catch (IOException e) {
out.println(String.format("docerina: API documentation zip packaging failed for %s: %s", output, e.getMessage()));
log.error(String.format("API documentation zip packaging failed for %s", output), e);
}
}
use of org.wso2.ballerinalang.compiler.semantics.analyzer.Types in project ballerina by ballerina-lang.
the class MultipartDecoderTest method testMultiplePartsForNewSubTypes.
@Test(description = "Test whether the requests with new multipart sub types can be decoded properly")
public void testMultiplePartsForNewSubTypes() {
String path = "/test/multipleparts";
List<Header> headers = new ArrayList<>();
String multipartDataBoundary = MimeUtil.getNewMultipartDelimiter();
headers.add(new Header(HttpHeaderNames.CONTENT_TYPE.toString(), "multipart/new-sub-type; boundary=" + multipartDataBoundary));
String multipartBody = "--" + multipartDataBoundary + "\r\n" + "Content-Disposition: form-data; name=\"foo\"" + "\r\n" + "Content-Type: text/plain; charset=UTF-8" + "\r\n" + "\r\n" + "Part1" + "\r\n" + "--" + multipartDataBoundary + "\r\n" + "Content-Disposition: inline" + "\r\n" + "Content-Type: text/plain" + "\r\n" + "Content-Transfer-Encoding: binary" + "\r\n" + "\r\n" + "Part2" + StringUtil.NEWLINE + "\r\n" + "--" + multipartDataBoundary + "--" + "\r\n";
HTTPTestRequest inRequestMsg = MessageUtils.generateHTTPMessage(path, HttpConstants.HTTP_METHOD_POST, headers, multipartBody);
HTTPCarbonMessage response = Services.invokeNew(serviceResult, MOCK_ENDPOINT_NAME, inRequestMsg);
Assert.assertNotNull(response, "Response message not found");
Assert.assertEquals(ResponseReader.getReturnValue(response), " -- Part1 -- Part2" + StringUtil.NEWLINE);
}
use of org.wso2.ballerinalang.compiler.semantics.analyzer.Types in project ballerina by ballerina-lang.
the class CommonUtil method generateJSON.
/**
* Generate json representation for the given node.
*
* @param node Node to get the json representation
* @param anonStructs Map of anonymous structs
* @return {@link JsonElement} Json Representation of the node
*/
public static JsonElement generateJSON(Node node, Map<String, Node> anonStructs) {
if (node == null) {
return JsonNull.INSTANCE;
}
Set<Method> methods = ClassUtils.getAllInterfaces(node.getClass()).stream().flatMap(aClass -> Arrays.stream(aClass.getMethods())).collect(Collectors.toSet());
JsonObject nodeJson = new JsonObject();
JsonArray wsJsonArray = new JsonArray();
Set<Whitespace> ws = node.getWS();
if (ws != null && !ws.isEmpty()) {
for (Whitespace whitespace : ws) {
JsonObject wsJson = new JsonObject();
wsJson.addProperty("ws", whitespace.getWs());
wsJson.addProperty("i", whitespace.getIndex());
wsJson.addProperty("text", whitespace.getPrevious());
wsJson.addProperty("static", whitespace.isStatic());
wsJsonArray.add(wsJson);
}
nodeJson.add("ws", wsJsonArray);
}
org.ballerinalang.util.diagnostic.Diagnostic.DiagnosticPosition position = node.getPosition();
if (position != null) {
JsonObject positionJson = new JsonObject();
positionJson.addProperty("startColumn", position.getStartColumn());
positionJson.addProperty("startLine", position.getStartLine());
positionJson.addProperty("endColumn", position.getEndColumn());
positionJson.addProperty("endLine", position.getEndLine());
nodeJson.add("position", positionJson);
}
JsonArray type = getType(node);
if (type != null) {
nodeJson.add(SYMBOL_TYPE, type);
}
if (node.getKind() == NodeKind.INVOCATION) {
assert node instanceof BLangInvocation : node.getClass();
BLangInvocation invocation = (BLangInvocation) node;
if (invocation.symbol != null && invocation.symbol.kind != null) {
nodeJson.addProperty(INVOCATION_TYPE, invocation.symbol.kind.toString());
}
}
for (Method m : methods) {
String name = m.getName();
if (name.equals("getWS") || name.equals("getPosition")) {
continue;
}
String jsonName;
if (name.startsWith("get")) {
jsonName = toJsonName(name, 3);
} else if (name.startsWith("is")) {
jsonName = toJsonName(name, 2);
} else {
continue;
}
Object prop = null;
try {
prop = m.invoke(node);
} catch (IllegalAccessException | InvocationTargetException e) {
logger.error("Error while serializing source to JSON: [" + e.getMessage() + "]");
}
/* Literal class - This class is escaped in backend to address cases like "ss\"" and 8.0 and null */
if (node.getKind() == NodeKind.LITERAL && "value".equals(jsonName)) {
if (prop instanceof String) {
nodeJson.addProperty(jsonName, '"' + StringEscapeUtils.escapeJava((String) prop) + '"');
nodeJson.addProperty(UNESCAPED_VALUE, String.valueOf(prop));
} else {
nodeJson.addProperty(jsonName, String.valueOf(prop));
}
continue;
}
if (node.getKind() == NodeKind.USER_DEFINED_TYPE && jsonName.equals("typeName")) {
IdentifierNode typeNode = (IdentifierNode) prop;
Node structNode;
if (typeNode.getValue().startsWith("$anonStruct$") && (structNode = anonStructs.remove(typeNode.getValue())) != null) {
JsonObject anonStruct = generateJSON(structNode, anonStructs).getAsJsonObject();
anonStruct.addProperty("anonStruct", true);
nodeJson.add("anonStruct", anonStruct);
continue;
}
}
if (prop instanceof List && jsonName.equals("types")) {
// Currently we don't need any Symbols for the UI. So skipping for now.
continue;
}
/* Node classes */
if (prop instanceof Node) {
nodeJson.add(jsonName, generateJSON((Node) prop, anonStructs));
} else if (prop instanceof List) {
List listProp = (List) prop;
JsonArray listPropJson = new JsonArray();
nodeJson.add(jsonName, listPropJson);
for (Object listPropItem : listProp) {
if (listPropItem instanceof Node) {
/* Remove top level anon func and struct */
if (node.getKind() == NodeKind.COMPILATION_UNIT) {
if (listPropItem instanceof BLangStruct && ((BLangStruct) listPropItem).isAnonymous) {
anonStructs.put(((BLangStruct) listPropItem).getName().getValue(), ((BLangStruct) listPropItem));
continue;
}
if (listPropItem instanceof BLangFunction && (((BLangFunction) listPropItem)).name.value.startsWith("$lambda$")) {
continue;
}
}
listPropJson.add(generateJSON((Node) listPropItem, anonStructs));
} else {
logger.debug("Can't serialize " + jsonName + ", has a an array of " + listPropItem);
}
}
/* Runtime model classes */
} else if (prop instanceof Set && jsonName.equals("flags")) {
Set flags = (Set) prop;
for (Flag flag : Flag.values()) {
nodeJson.addProperty(StringUtils.lowerCase(flag.toString()), flags.contains(flag));
}
} else if (prop instanceof Set) {
// TODO : limit this else if to getInputs getOutputs of transform.
Set vars = (Set) prop;
JsonArray listVarJson = new JsonArray();
nodeJson.add(jsonName, listVarJson);
for (Object obj : vars) {
listVarJson.add(obj.toString());
}
} else if (prop instanceof NodeKind) {
String kindName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, prop.toString());
nodeJson.addProperty(jsonName, kindName);
} else if (prop instanceof OperatorKind) {
nodeJson.addProperty(jsonName, prop.toString());
/* Generic classes */
} else if (prop instanceof String) {
nodeJson.addProperty(jsonName, (String) prop);
} else if (prop instanceof Number) {
nodeJson.addProperty(jsonName, (Number) prop);
} else if (prop instanceof Boolean) {
nodeJson.addProperty(jsonName, (Boolean) prop);
} else if (prop instanceof Enum) {
nodeJson.addProperty(jsonName, StringUtils.lowerCase(((Enum) prop).name()));
} else if (prop != null) {
nodeJson.addProperty(jsonName, prop.toString());
String message = "Node " + node.getClass().getSimpleName() + " contains unknown type prop: " + jsonName + " of type " + prop.getClass();
logger.error(message);
}
}
return nodeJson;
}
Aggregations