blob: b8410472d726303a573a93de4425862b43ab7ace [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.adobe.ac.pmd.nodes.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import com.adobe.ac.pmd.nodes.IAttribute;
import com.adobe.ac.pmd.nodes.IClass;
import com.adobe.ac.pmd.nodes.IConstant;
import com.adobe.ac.pmd.nodes.IFunction;
import com.adobe.ac.pmd.nodes.IMetaData;
import com.adobe.ac.pmd.nodes.MetaData;
import com.adobe.ac.pmd.nodes.Modifier;
import com.adobe.ac.pmd.parser.IParserNode;
import com.adobe.ac.pmd.parser.NodeKind;
class ClassNode extends AbstractNode implements IClass
{
private IParserNode asDoc;
private final List< IAttribute > attributes;
private IParserNode block;
private final List< IConstant > constants;
private IFunction constructor;
private String extensionName;
private final List< IFunction > functions;
private List< IParserNode > implementations;
private final Map< MetaData, List< IMetaData > > metaDataList;
private final Set< Modifier > modifiers;
private final List< IParserNode > multiLinesComments;
private IdentifierNode name;
/**
* @param node
*/
protected ClassNode( final IParserNode node )
{
super( node );
modifiers = new HashSet< Modifier >();
metaDataList = new LinkedHashMap< MetaData, List< IMetaData > >();
implementations = new ArrayList< IParserNode >();
constants = new ArrayList< IConstant >();
attributes = new ArrayList< IAttribute >();
functions = new ArrayList< IFunction >();
multiLinesComments = new ArrayList< IParserNode >();
name = null;
asDoc = null;
}
/*
* (non-Javadoc)
* @see
* com.adobe.ac.pmd.nodes.IMetaDataListHolder#add(com.adobe.ac.pmd.nodes.
* IMetaData)
*/
public void add( final IMetaData metaData )
{
final MetaData metaDataImpl = MetaData.create( metaData.getName() );
if ( !metaDataList.containsKey( metaDataImpl ) )
{
metaDataList.put( metaDataImpl,
new ArrayList< IMetaData >() );
}
metaDataList.get( metaDataImpl ).add( metaData );
}
/*
* (non-Javadoc)
* @see
* com.adobe.ac.pmd.nodes.IModifiersHolder#add(com.adobe.ac.pmd.nodes.Modifier
* )
*/
public void add( final Modifier modifier )
{
modifiers.add( modifier );
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.impl.AbstractNode#compute()
*/
@Override
public ClassNode compute()
{
if ( getInternalNode().numChildren() != 0 )
{
for ( final IParserNode node : getInternalNode().getChildren() )
{
if ( node.is( NodeKind.CONTENT ) )
{
computeClassContent( node );
}
else if ( node.is( NodeKind.MOD_LIST ) )
{
computeModifierList( this,
node );
}
else if ( node.is( NodeKind.NAME ) )
{
name = IdentifierNode.create( node );
}
else if ( node.is( NodeKind.META_LIST ) )
{
computeMetaDataList( this,
node );
}
else if ( node.is( NodeKind.AS_DOC ) )
{
asDoc = node;
}
else if ( node.is( NodeKind.MULTI_LINE_COMMENT ) )
{
multiLinesComments.add( node );
}
detectImplementations( node );
detectExtensions( node );
}
for ( final IFunction function : functions )
{
if ( name.toString().equals( function.getName() ) )
{
constructor = function;
}
}
}
return this;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IMetaDataListHolder#getAllMetaData()
*/
public List< IMetaData > getAllMetaData()
{
final List< IMetaData > list = new ArrayList< IMetaData >();
for ( final Entry< MetaData, List< IMetaData > > entry : metaDataList.entrySet() )
{
list.addAll( entry.getValue() );
}
return list;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IAsDocHolder#getAsDoc()
*/
public IParserNode getAsDoc()
{
return asDoc;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#getAttributes()
*/
public List< IAttribute > getAttributes()
{
return attributes;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#getAverageCyclomaticComplexity()
*/
public double getAverageCyclomaticComplexity()
{
if ( functions.isEmpty() )
{
return 0;
}
int totalCcn = 0;
for ( final IFunction function : functions )
{
totalCcn += function.getCyclomaticComplexity();
}
return totalCcn
/ functions.size();
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#getBlock()
*/
public final IParserNode getBlock()
{
return block;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#getConstants()
*/
public List< IConstant > getConstants()
{
return constants;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#getConstructor()
*/
public IFunction getConstructor()
{
return constructor;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#getExtensionName()
*/
public String getExtensionName()
{
return extensionName;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#getFunctions()
*/
public List< IFunction > getFunctions()
{
return functions;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#getImplementations()
*/
public List< IParserNode > getImplementations()
{
return implementations;
}
/*
* (non-Javadoc)
* @see
* com.adobe.ac.pmd.nodes.IMetaDataListHolder#getMetaData(com.adobe.ac.pmd
* .nodes.MetaData)
*/
public List< IMetaData > getMetaData( final MetaData metaDataName )
{
if ( metaDataList.containsKey( metaDataName ) )
{
return metaDataList.get( metaDataName );
}
else
{
return new ArrayList< IMetaData >();
}
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IMetaDataListHolder#getMetaDataCount()
*/
public int getMetaDataCount()
{
return metaDataList.size();
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.ICommentHolder#getMultiLinesComment()
*/
public List< IParserNode > getMultiLinesComment()
{
return multiLinesComments;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.INamable#getName()
*/
public String getName()
{
return name.toString();
}
/*
* (non-Javadoc)
* @see
* com.adobe.ac.pmd.nodes.IModifiersHolder#is(com.adobe.ac.pmd.nodes.Modifier
* )
*/
public boolean is( final Modifier modifier ) // NOPMD
{
return modifiers.contains( modifier );
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#isBindable()
*/
public boolean isBindable()
{
return metaDataList.get( MetaData.BINDABLE ) != null;
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IClass#isFinal()
*/
public boolean isFinal()
{
return is( Modifier.FINAL );
}
/*
* (non-Javadoc)
* @see com.adobe.ac.pmd.nodes.IVisible#isPublic()
*/
public boolean isPublic()
{
return is( Modifier.PUBLIC );
}
private void computeClassContent( final IParserNode classContentNode )
{
if ( classContentNode.numChildren() != 0 )
{
for ( final IParserNode node : classContentNode.getChildren() )
{
detectBlock( node );
detectFunction( node );
detectAttribute( node );
detectConstant( node );
if ( node.is( NodeKind.MULTI_LINE_COMMENT ) )
{
multiLinesComments.add( node );
}
}
}
}
private void detectAttribute( final IParserNode node )
{
if ( node.is( NodeKind.VAR_LIST ) )
{
attributes.add( new AttributeNode( node ).compute() );
}
}
private void detectBlock( final IParserNode node )
{
if ( node.is( NodeKind.BLOCK ) )
{
block = node;
}
}
private void detectConstant( final IParserNode node )
{
if ( node.is( NodeKind.CONST_LIST ) )
{
constants.add( new ConstantNode( node ).compute() );
}
}
private void detectExtensions( final IParserNode node )
{
if ( node.is( NodeKind.EXTENDS ) )
{
extensionName = node.getStringValue();
}
}
private void detectFunction( final IParserNode node )
{
if ( node.is( NodeKind.FUNCTION )
|| node.is( NodeKind.GET ) || node.is( NodeKind.SET ) )
{
functions.add( new FunctionNode( node ).compute() );
}
}
private void detectImplementations( final IParserNode node )
{
if ( node.is( NodeKind.IMPLEMENTS_LIST ) )
{
implementations = node.getChildren();
}
}
}