Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
gw.gosudoc.doc.GSRootDocImpl.gs Maven / Gradle / Ivy
Go to download
Generates Javadoc-compatible documentation for Gosu projects
package gw.gosudoc.doc
uses gw.gosudoc.com.sun.javadoc.RootDoc
uses gw.gosudoc.com.sun.javadoc.ClassDoc
uses gw.gosudoc.com.sun.javadoc.PackageDoc
uses gw.gosudoc.com.sun.javadoc.SourcePosition
uses gw.gosudoc.filter.*
uses gw.gosudoc.type.GSArrayTypeImpl
uses gw.gosudoc.type.GSClassTypeImpl
uses gw.gosudoc.type.GSFunctionalTypeImpl
uses gw.gosudoc.type.GSParameterizedTypeImpl
uses gw.gosudoc.type.GSPrimitiveTypeImpl
uses gw.gosudoc.type.GSTypeImpl
uses gw.gosudoc.type.GSTypeVariableImpl
uses gw.gosudoc.type.GSVoidTypeImpl
uses gw.lang.reflect.IConstructorInfo
uses gw.lang.reflect.IFunctionType
uses gw.lang.reflect.IMethodInfo
uses gw.lang.reflect.IPropertyInfo
uses gw.lang.reflect.IType
uses gw.lang.reflect.ITypeVariableType
uses gw.lang.reflect.TypeSystem
uses gw.lang.reflect.gs.IGosuClass
uses java.io.File
uses java.lang.System
uses java.util.ArrayList
uses java.util.HashMap
uses java.util.IdentityHashMap
uses java.util.regex.Pattern
class GSRootDocImpl extends GSDocImpl implements RootDoc{
static var GOSU_SOURCE_EXTENSIONS : Set = {"gs", "gsx"}
var _voidType = new GSVoidTypeImpl( this )
var _typesByType = new IdentityHashMap()
var _packagesByName = new HashMap().toAutoMap( \name -> new GSPackageDocImpl( name, this ) )
// Config info
var _externalDocs : List as ExternalDocs = {}
private final var _filesToDoc: Set
var _exclusions : List as Exclusions = {}
var _outputDirectory : File as OutputDirectory
var _typeFilters : List as readonly TypeFilters = {}
var _methodFilters : List as readonly MethodFilters = {}
var _propertyFilters : List as readonly PropertyFilters = {}
var _constructorFilters : List as readonly ConstructorFilters = {}
var _featureFilters : List as readonly FeatureFilters = {}
var _pathFilters : List as readonly PathFilters = {}
var _verbose: boolean
construct( inputDirs : List, outputDir: File, filters : List = null,
externalDocs : List = null, verbose = false ){
super( "Root", null )
_verbose = verbose
_outputDirectory = outputDir
_externalDocs = externalDocs
if(filters != null) {
initFilters(filters)
}
_filesToDoc = typesToDoc(inputDirs)
}
private function typesToDoc(inputDirs: List): Set {
debug(\-> "Beginning souce file scan")
var types = new HashSet()
for(file in inputDirs) {
addTypesToDoc(file, file, types);
}
debug(\-> "Finished souce file scan")
return types
}
private function addTypesToDoc(root : File, file: File, types: HashSet) {
if(shouldIncludeFile(file.AbsolutePath)) {
if(file.Directory) {
debug(\-> " Scanning " + file.AbsolutePath)
for(child in file.Children) {
addTypesToDoc(root, child, types)
}
} else {
if(GOSU_SOURCE_EXTENSIONS.contains(file.Extension)) {
var typeName = computeTypeName(root, file)
debug(\-> " Adding " + file.AbsolutePath + " as " + typeName)
types.add(typeName)
}
}
} else {
debug(\-> " Ignoring " + file.AbsolutePath)
}
}
private function debug(s: block():String) {
if(_verbose) {
print(s())
}
}
private function computeTypeName(root: File, file: File): String {
var absolutePath = file.AbsolutePath
var relativePath = absolutePath.substring(root.AbsolutePath.length )
var withoutExtension = relativePath.substring(1, relativePath.length - file.Extension.length - 1 )
var asTypeName = withoutExtension.replace(File.separatorChar, '.')
return asTypeName
}
private function shouldIncludeFile(absolutePath: String): boolean {
return not _pathFilters.hasMatch(\ f -> not f.shouldIncludePath( absolutePath ) )
}
private function initFilters( filters: List ){
for(o in filters) {
if(o typeis TypeFilter) TypeFilters.add(o)
if(o typeis MethodFilter ) MethodFilters.add(o)
if(o typeis PropertyFilter ) PropertyFilters.add(o)
if(o typeis ConstructorFilter ) ConstructorFilters.add(o)
if(o typeis FeatureFilter ) FeatureFilters.add(o)
}
}
function shouldDocumentType( iType : Type ): boolean{
var shouldDoc = shouldDocumentTypeImpl(iType);
debug(\ -> iType.Name + " - document : " + shouldDoc)
return shouldDoc;
}
private function shouldDocumentTypeImpl(iType: Type): boolean{
if(isExcluded( iType.Name )) {
return false
}
for(filter in TypeFilters) {
if(not filter.shouldIncludeType( iType )) {
return false
}
}
if(iType typeis IGosuClass ) {
if(_filesToDoc.contains(iType.Name)) {
return true;
}
if(iType.EnclosingType typeis Type) {
return shouldDocumentType(iType.EnclosingType)
}
}
return false
}
function isExcluded( name: String ): boolean{
return _exclusions.hasMatch( \p -> p.matcher( name ).find() ) || isSynthetic( name )
}
function isSynthetic( name: String ): boolean{
return name.endsWith( ".PLACEHOLDER" ) ||
name.startsWith( "_proxy_" ) ||
name.startsWith( "OSGI-OPT" ) ||
name.contains( ".block_" ) ||
name.contains( ".AnonymouS__" ) ||
name.contains( ".ProxyFor_" ) ||
name.equals( 'Key' )
}
override function options(): String[][]{
var l = new ArrayList()
for( externalJavadoc in _externalDocs ){
l.add( {"-link", externalJavadoc} )
}
l.add( {"-d", _outputDirectory.getCanonicalPath()} )
return l.toTypedArray()
}
function genDocs(){
printNotice( "Loading types to generate GosuDoc" )
for( typeName in TypeSystem.getAllTypeNames() ){
try{
if(!isExcluded( typeName.toString() )) {
var iType = TypeSystem.getByFullName( typeName.toString() )
if( shouldDocumentType( iType ) ){
getOrCreateClass( iType )
}
}
} catch( e ){
printWarning( "Could not load type ${typeName}: ${e.Message}" )
}
}
}
override function specifiedPackages(): PackageDoc[]{
return getAllPackages()
}
override function specifiedClasses(): ClassDoc[]{
return classes()
}
override function classes(): ClassDoc[]{
return specifiedPackages().flatMap( \elt -> elt.allClasses() )
}
override function packageNamed( name: String ): GSPackageDocImpl{
return _packagesByName.get( name )
}
override function classNamed( qualifiedName: String ): ClassDoc{
var packageName = getPackageNameFromTypeName( qualifiedName )
return packageNamed( packageName ).findClass( qualifiedName )
}
override function printError( msg: String ){
System.err.println( "ERROR: ${msg}}" )
}
override function printError( pos: SourcePosition, msg: String ){
System.err.println( "ERROR: ${msg} ${processPos( pos )}" )
}
override function printWarning( msg: String ){
if( warningIsUnexpected( msg ) ){
System.err.println( "WARNING: ${msg}}" )
}
}
override function printWarning( pos: SourcePosition, msg: String ){
if( warningIsUnexpected( msg ) ){
System.err.println( "WARNING: ${msg} ${processPos( pos )}" )
}
}
override function printNotice( msg: String ){
System.out.println( msg )
}
override function printNotice( pos: SourcePosition, msg: String ){
System.out.println( "${msg} ${pos}" )
}
function getOrCreateClass( iType: IType ): GSClassDocImpl {
var baseType = getBaseClassType( iType )
var className = iType.Name
var pack = packageNamed( baseType.getNamespace() ?: "" )
var clazz = pack.findClass( className )
if( clazz == null ){
clazz = pack.addClass( baseType )
}
return clazz
}
// Returns empty string for default package.
function getPackageNameFromTypeName( fqtn: String ): String{
var i = fqtn.lastIndexOf( "." )
var packagePortion = i >= 0 ? fqtn.substring( 0, i ) : ""
return packagePortion
}
function getType( type: IType, owner: GSProgramElementDocImpl ): GSTypeImpl {
if( type == null ){
// there are some weird methods that have null return type.
return _voidType
}
var typeImpl = _typesByType.get( type )
if( typeImpl == null ){
if( type.isArray() ){
typeImpl = new GSArrayTypeImpl( type, this, owner )
} else if( isVoid( type ) ){
typeImpl = _voidType
} else if( type.isPrimitive() ){
typeImpl = new GSPrimitiveTypeImpl( type, this, owner )
} else if( type typeis IFunctionType ){ // handle blocks, etc.
typeImpl = new GSFunctionalTypeImpl( type, this, owner )
} else if( type typeis ITypeVariableType ){
typeImpl = new GSTypeVariableImpl( type.Name, type.BoundingType, this, owner )
} else if( type.isParameterizedType() ){
typeImpl = new GSParameterizedTypeImpl( type, this, owner )
} else{
typeImpl = new GSClassTypeImpl( type, this, owner )
}
_typesByType.put( type, typeImpl )
typeImpl.initialize()
}
return typeImpl
}
function getAllPackages(): PackageDoc[]{
return _packagesByName.values().where( \elt -> elt.Included ).toTypedArray()
}
private function getBaseClassType( iType: IType ): IType {
if( iType == null ){
return null
}
if( iType.isArray() ){
return getBaseClassType( iType.getComponentType() )
}
if( iType.isPrimitive() ){
return iType
}
if( iType typeis ITypeVariableType ){
return getBaseClassType( iType.BoundingType )
}
if( iType.isParameterizedType() ){
return getBaseClassType( iType.getGenericType() )
}
return iType
}
private function processPos( pos: SourcePosition ) : Object {
return pos ?: ""
}
private function warningIsUnexpected( msg: String ): boolean{
return !(msg.startsWith( "Parameter" ) && msg.contains( " is documented more than once" ))
}
function shouldDocumentConstructor( iConstructorInfo: IConstructorInfo ): boolean{
for(filter in ConstructorFilters) {
if(not filter.shouldIncludeConstructor( iConstructorInfo )) {
return false
}
}
for(filter in FeatureFilters) {
if(not filter.shouldIncludeFeature( iConstructorInfo )) {
return false
}
}
return true
}
function shouldDocumentProperty( iPropertyInfo: IPropertyInfo ): boolean{
for(filter in PropertyFilters) {
if(not filter.shouldIncludeProperty( iPropertyInfo )) {
return false
}
}
for(filter in FeatureFilters) {
if(not filter.shouldIncludeFeature( iPropertyInfo )) {
return false
}
}
return true
}
function shouldDocumentMethod( iMethodInfo: IMethodInfo ): boolean{
for(filter in MethodFilters) {
if(not filter.shouldIncludeMethod( iMethodInfo )) {
return false
}
}
for(filter in FeatureFilters) {
if(not filter.shouldIncludeFeature( iMethodInfo )) {
return false
}
}
return true
}
}