/**
 * Copyright (c) 2016-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import * as Either from './either' ; import * as Error from './error' ; import * as CLangCommon from './clang-common' ; import * as Maybe from './maybe' ; import * as ObjectGeneration from './object-generation' ; export function possiblyUndefinedStringToMaybe ( str ) { if ( str == null ) { return null ; } else { return str ; } } function annotationValuesFromAnnotations ( annotations , annotationName ) { if ( annotations !== undefined && annotations [ annotationName ] != null ) { return annotations [ annotationName ] ; } else { return null ; } } function libraryNameFromAnnotation ( annotation ) { if ( annotation != null && annotation [ 'name' ] != null ) { return annotation [ 'name' ] ; } else { return null ; } } export function libraryNameFromAnnotations ( annotations ) { const libraryDefinitions = annotationValuesFromAnnotations ( annotations , 'library' ) ; return Maybe . match ( function ( annotationValues ) { return libraryNameFromAnnotation ( annotationValues [ annotationValues . length - 1 ] ) ; } , function ( ) { return null ; } , libraryDefinitions ) ; } export function nullabilityFromParseResultAnnotations ( annotations ) { if ( annotations [ 'nonnull' ] !== undefined ) { return CLangCommon . Nullability . Nonnull ( ) ; } else if ( annotations [ 'nullable' ] !== undefined ) { return CLangCommon . Nullability . Nullable ( ) ; } else { return CLangCommon . Nullability . Inherited ( ) ; } } function importAnnotationFromAnnotations ( annotations ) { const importDefinitions = annotationValuesFromAnnotations ( annotations , 'import' ) ; return Maybe . map ( function ( annotationValues ) { return annotationValues [ annotationValues . length - 1 ] ; } , importDefinitions ) ; } export function valueFromImportAnnotationFromAnnotations ( annotations , key ) { const importAnnotation = importAnnotationFromAnnotations ( annotations ) ; return Maybe . match ( function ( annotation ) { return annotation [ key ] != null ? annotation [ key ] : null ; } , function ( ) { return null ; } , importAnnotation ) ; } const STRING_VALUES_TO_CONVERT_TO_FALSE = [ 'false' , '0' ] ; function booleanFromString ( s , defaultValue ) { if ( s != null ) { return STRING_VALUES_TO_CONVERT_TO_FALSE . indexOf ( s ) === - 1 ; } else { return defaultValue ; } } function collectTypeLookups ( soFar , typeDefinition ) { if ( typeDefinition [ 'name' ] != null ) { return Either . map ( function ( typeLookups ) { return typeLookups . concat ( { name : typeDefinition [ 'name' ] , library : possiblyUndefinedStringToMaybe ( typeDefinition [ 'library' ] ) , file : possiblyUndefinedStringToMaybe ( typeDefinition [ 'file' ] ) , canForwardDeclare : booleanFromString ( typeDefinition [ 'canForwardDeclare' ] , true ) } ) ; } , soFar ) ; } else { return Either . match ( function ( errors ) { return Either . Left < Error . Error [ ] , ObjectGeneration . TypeLookup [ ] > ( errors . concat ( Error . Error ( 'Invalid type annotation' ) ) ) ; } , function ( typeLookups ) { return Either . Left < Error . Error [ ] , ObjectGeneration . TypeLookup [ ] > ( [ Error . Error ( 'Invalid type annotation' ) , ] ) ; } , soFar ) ; } } export function typeLookupsFromRawAnnotations ( annotations ) { const typeDefinitions = annotationValuesFromAnnotations ( annotations , 'type' ) ; return Maybe . match ( function ( annotationValues ) { return annotationValues . reduce ( collectTypeLookups , Either . Right < Error . Error [ ] , ObjectGeneration . TypeLookup [ ] > ( [ ] ) ) ; } , function ( ) { return Either . Right < Error . Error [ ] , ObjectGeneration . TypeLookup [ ] > ( [ ] ) ; } , typeDefinitions ) ; } export function typeLookupsFromAnnotations ( annotations ) { return Maybe . match ( function ( annotations ) { const annotationProperties = annotations . map ( function ( annotation ) : { [ key ] : string ; } { return annotation . properties ; } ) ; return annotationProperties . reduce ( collectTypeLookups , Either . Right < Error . Error [ ] , ObjectGeneration . TypeLookup [ ] > ( [ ] ) ) ; } , function ( ) { return Either . Right < Error . Error [ ] , ObjectGeneration . TypeLookup [ ] > ( [ ] ) ; } , annotations ) ; } export function foundAnnotationFromParsedAnnotations ( parsedAnnotations ) { const foundAnnotations = { } ; for ( const parsedAnnotationName in parsedAnnotations ) { foundAnnotations [ parsedAnnotationName ] = parsedAnnotations [ parsedAnnotationName ] . map ( function ( parsedInstance ) : ObjectGeneration . Annotation { return { properties : parsedInstance } ; } ) ; } return foundAnnotations ; }