forked from phoedos/pmd
[modelica] Initial implementation of Modelica support for PMD
This commit is contained in:
parent
78c8ea2749
commit
20bf4ad759
@ -9,10 +9,10 @@
|
||||
|
||||
**PMD** is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks,
|
||||
unnecessary object creation, and so forth. It supports Java, JavaScript, Salesforce.com Apex and Visualforce,
|
||||
PLSQL, Apache Velocity, XML, XSL, Scala.
|
||||
Modelica, PLSQL, Apache Velocity, XML, XSL, Scala.
|
||||
|
||||
Additionally it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in
|
||||
C/C++, C#, Dart, Fortran, Go, Groovy, Java, JavaScript, JSP, Kotlin, Lua, Matlab,
|
||||
C/C++, C#, Dart, Fortran, Go, Groovy, Java, JavaScript, JSP, Kotlin, Lua, Matlab, Modelica,
|
||||
Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex, Scala, Swift and Visualforce.
|
||||
|
||||
## Source and Documentation
|
||||
|
@ -162,6 +162,11 @@
|
||||
<artifactId>pmd-matlab</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-modelica</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-perl</artifactId>
|
||||
|
@ -66,7 +66,7 @@ public class BinaryDistributionIT extends AbstractBinaryDistributionTest {
|
||||
|
||||
result = PMDExecutor.runPMD(tempDir, "-h");
|
||||
// note: the language "text" is provided by pmd-designer
|
||||
result.assertExecutionResult(0, "apex, ecmascript, java, jsp, plsql, pom, scala, text, vf, vm, wsdl, xml, xsl");
|
||||
result.assertExecutionResult(0, "apex, ecmascript, java, jsp, modelica, plsql, pom, scala, text, vf, vm, wsdl, xml, xsl");
|
||||
|
||||
result = PMDExecutor.runPMDRules(tempDir, srcDir, "src/test/resources/rulesets/sample-ruleset.xml");
|
||||
result.assertExecutionResult(4, "", "JumbledIncrementer.java:8:");
|
||||
@ -82,7 +82,7 @@ public class BinaryDistributionIT extends AbstractBinaryDistributionTest {
|
||||
ExecutionResult result;
|
||||
|
||||
result = CpdExecutor.runCpd(tempDir, "-h");
|
||||
result.assertExecutionResult(0, "Supported languages: [apex, cpp, cs, dart, ecmascript, fortran, go, groovy, java, jsp, kotlin, lua, matlab, objectivec, perl, php, plsql, python, ruby, scala, swift, vf]");
|
||||
result.assertExecutionResult(0, "Supported languages: [apex, cpp, cs, dart, ecmascript, fortran, go, groovy, java, jsp, kotlin, lua, matlab, modelica, objectivec, perl, php, plsql, python, ruby, scala, swift, vf]");
|
||||
|
||||
result = CpdExecutor.runCpd(tempDir, "--minimum-tokens", "10", "--format", "text", "--files", srcDir);
|
||||
result.assertExecutionResult(4, "Found a 10 line (55 tokens) duplication in the following files:");
|
||||
|
989
pmd-modelica/etc/grammar/Modelica.jjt
Normal file
989
pmd-modelica/etc/grammar/Modelica.jjt
Normal file
File diff suppressed because it is too large
Load Diff
83
pmd-modelica/pom.xml
Normal file
83
pmd-modelica/pom.xml
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>pmd-modelica</artifactId>
|
||||
<name>PMD Modelica</name>
|
||||
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.21.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<configuration>
|
||||
<useDefaultDelimiters>false</useDefaultDelimiters>
|
||||
<delimiters>
|
||||
<delimiter>${*}</delimiter>
|
||||
</delimiters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<inherited>true</inherited>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="src/main/ant/alljavacc.xml">
|
||||
<property name="target" value="${project.build.directory}/generated-sources/javacc" />
|
||||
<property name="javacc.jar" value="${settings.localRepository}/net/java/dev/javacc/javacc/${javacc.version}/javacc-${javacc.version}.jar" />
|
||||
</ant>
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-javacc-generated-sources</id>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${project.build.directory}/generated-sources/javacc</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
157
pmd-modelica/src/main/ant/alljavacc.xml
Normal file
157
pmd-modelica/src/main/ant/alljavacc.xml
Normal file
@ -0,0 +1,157 @@
|
||||
<project name="pmd" default="alljavacc" basedir="../../">
|
||||
|
||||
<property name="javacc-home.path" value="target/lib" />
|
||||
|
||||
<target name="alljavacc"
|
||||
description="Generates all JavaCC aspects within PMD Modelica"
|
||||
depends="checkUpToDate,init,modelicajjtree,cleanup" />
|
||||
|
||||
<target name="checkUpToDate">
|
||||
<uptodate property="javaccBuildNotRequired" targetfile="${target}/last-generated-timestamp">
|
||||
<srcfiles dir="etc/grammar" includes="*.jj*"/>
|
||||
</uptodate>
|
||||
<echo message="up to date check: javaccBuildNotRequired=${javaccBuildNotRequired}"/>
|
||||
</target>
|
||||
|
||||
<target name="init" unless="javaccBuildNotRequired">
|
||||
<mkdir dir="${javacc-home.path}" />
|
||||
<copy file="${javacc.jar}" tofile="${javacc-home.path}/javacc.jar" />
|
||||
|
||||
<mkdir dir="${target}"/>
|
||||
<touch file="${target}/last-generated-timestamp"/>
|
||||
</target>
|
||||
|
||||
<target name="cleanup">
|
||||
<delete dir="${javacc-home.path}" />
|
||||
</target>
|
||||
|
||||
<target name="modelicajjtree" description="Generates the Modelica parser and AST source files" unless="javaccBuildNotRequired">
|
||||
<delete dir="${target}/net/sourceforge/pmd/lang/modelica/ast" />
|
||||
<mkdir dir="${target}/net/sourceforge/pmd/lang/modelica/ast" />
|
||||
<jjtree target="etc/grammar/Modelica.jjt"
|
||||
outputdirectory="${target}/net/sourceforge/pmd/lang/modelica/ast"
|
||||
javacchome="${javacc-home.path}" />
|
||||
<!-- Ensure generated using CharStream interface -->
|
||||
<javacc static="false"
|
||||
usercharstream="true"
|
||||
target="${target}/net/sourceforge/pmd/lang/modelica/ast/Modelica.jj"
|
||||
outputdirectory="${target}/net/sourceforge/pmd/lang/modelica/ast"
|
||||
javacchome="${javacc-home.path}" />
|
||||
<delete file="${target}/net/sourceforge/pmd/lang/modelica/ast/Node.java" />
|
||||
<delete file="${target}/net/sourceforge/pmd/lang/modelica/ast/SimpleNode.java" />
|
||||
<delete file="${target}/net/sourceforge/pmd/lang/modelica/ast/CharStream.java" />
|
||||
<delete file="${target}/net/sourceforge/pmd/lang/modelica/ast/TokenMgrError.java" />
|
||||
|
||||
<replace file="${target}/net/sourceforge/pmd/lang/modelica/ast/ModelicaParserTokenManager.java"
|
||||
token="class ModelicaParserTokenManager"
|
||||
value="class ModelicaParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" />
|
||||
<replace file="${target}/net/sourceforge/pmd/lang/modelica/ast/ModelicaParser.java"
|
||||
token="throw new Error"
|
||||
value="throw new RuntimeException" />
|
||||
<replace file="${target}/net/sourceforge/pmd/lang/modelica/ast/ParseException.java"
|
||||
token="extends Exception"
|
||||
value="extends net.sourceforge.pmd.lang.ast.ParseException" />
|
||||
<replace file="${target}/net/sourceforge/pmd/lang/modelica/ast/ModelicaParserVisitor.java"
|
||||
token="SimpleNode"
|
||||
value="AbstractModelicaNode" />
|
||||
<replace file="${target}/net/sourceforge/pmd/lang/modelica/ast/JJTModelicaParserState.java">
|
||||
<replacetoken>public class</replacetoken>
|
||||
<replacevalue><![CDATA[import net.sourceforge.pmd.lang.ast.Node;
|
||||
|
||||
public class]]></replacevalue>
|
||||
</replace>
|
||||
|
||||
<replace file="${target}/net/sourceforge/pmd/lang/modelica/ast/Token.java">
|
||||
<replacetoken><![CDATA[ default : return new Token(ofKind, image);
|
||||
}
|
||||
}
|
||||
]]></replacetoken>
|
||||
<replacevalue><![CDATA[
|
||||
default : return new Token(ofKind, image);
|
||||
}
|
||||
}
|
||||
]]></replacevalue>
|
||||
</replace>
|
||||
|
||||
<replace file="${target}/net/sourceforge/pmd/lang/modelica/ast/Token.java">
|
||||
<replacetoken>public class Token implements java.io.Serializable</replacetoken>
|
||||
<replacevalue><![CDATA[import net.sourceforge.pmd.lang.ast.GenericToken;
|
||||
|
||||
public class Token implements GenericToken, java.io.Serializable]]></replacevalue>
|
||||
</replace>
|
||||
|
||||
<!--Add implementation methods of GenericToken-->
|
||||
<replace file="${target}/net/sourceforge/pmd/lang/modelica/ast/Token.java">
|
||||
<replacetoken>public Token specialToken;</replacetoken>
|
||||
<replacevalue><![CDATA[public Token specialToken;
|
||||
|
||||
@Override
|
||||
public GenericToken getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericToken getPreviousComment() {
|
||||
return specialToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeginLine() {
|
||||
return beginLine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndLine() {
|
||||
return endLine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeginColumn() {
|
||||
return beginColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndColumn() {
|
||||
return endColumn;
|
||||
}
|
||||
|
||||
]]></replacevalue>
|
||||
</replace>
|
||||
<replace>
|
||||
<fileset dir="${target}/net/sourceforge/pmd/lang/modelica/ast">
|
||||
<include name="AST*.java" />
|
||||
</fileset>
|
||||
<replacetoken>SimpleNode</replacetoken>
|
||||
<replacevalue>AbstractModelicaNode</replacevalue>
|
||||
</replace>
|
||||
|
||||
<delete>
|
||||
<fileset dir="${target}/net/sourceforge/pmd/lang/modelica/ast">
|
||||
<include name="ASTStoredDefinition.java" />
|
||||
<include name="ASTWithinClause.java" />
|
||||
<include name="ASTElementList.java" />
|
||||
|
||||
<include name="ASTClassDefinition.java" />
|
||||
<include name="ASTDerClassSpecifier.java" />
|
||||
<include name="ASTEnumerationShortClassSpecifier.java" />
|
||||
<include name="ASTExtendingLongClassSpecifier.java" />
|
||||
<include name="ASTSimpleLongClassSpecifier.java" />
|
||||
<include name="ASTSimpleShortClassSpecifier.java" />
|
||||
|
||||
<include name="ASTName.java" />
|
||||
<include name="ASTComponentReference.java" />
|
||||
|
||||
<include name="ASTRenamingImportClause.java" />
|
||||
<include name="ASTSingleDefinitionImportClause.java" />
|
||||
<include name="ASTMultipleDefinitionImportClause.java" />
|
||||
<include name="ASTUnqualifiedImportClause.java" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
</target>
|
||||
</project>
|
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.cpd;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.ModelicaLanguageModule;
|
||||
|
||||
public class ModelicaLanguage extends AbstractLanguage {
|
||||
public ModelicaLanguage() {
|
||||
super(ModelicaLanguageModule.NAME, ModelicaLanguageModule.TERSE_NAME, new ModelicaTokenizer(), ".mo");
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.cpd;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer;
|
||||
import net.sourceforge.pmd.cpd.token.JavaCCTokenFilter;
|
||||
import net.sourceforge.pmd.lang.TokenManager;
|
||||
import net.sourceforge.pmd.lang.ast.GenericToken;
|
||||
import net.sourceforge.pmd.lang.modelica.ModelicaTokenManager;
|
||||
import net.sourceforge.pmd.lang.modelica.ast.ModelicaParser;
|
||||
import net.sourceforge.pmd.lang.modelica.ast.Token;
|
||||
|
||||
|
||||
public class ModelicaTokenizer extends JavaCCTokenizer {
|
||||
@Override
|
||||
protected TokenManager getLexerForSource(SourceCode sourceCode) {
|
||||
final StringBuilder stringBuilder = sourceCode.getCodeBuffer();
|
||||
return new ModelicaTokenManager(new StringReader(stringBuilder.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JavaCCTokenFilter getTokenFilter(TokenManager tokenManager) {
|
||||
return new ModelicaTokenFilter(tokenManager);
|
||||
}
|
||||
|
||||
public static class ModelicaTokenFilter extends JavaCCTokenFilter {
|
||||
private boolean discardingWithinAndImport = false;
|
||||
private boolean discardingAnnotation = false;
|
||||
|
||||
ModelicaTokenFilter(TokenManager tokenManager) {
|
||||
super(tokenManager);
|
||||
}
|
||||
|
||||
private void skipWithinAndImport(Token currentToken) {
|
||||
final int type = currentToken.kind;
|
||||
if (type == ModelicaParser.IMPORT || type == ModelicaParser.WITHIN) {
|
||||
discardingWithinAndImport = true;
|
||||
} else if (discardingWithinAndImport && type == ModelicaParser.SC) {
|
||||
discardingWithinAndImport = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void skipAnnotation(Token currentToken) {
|
||||
final int type = currentToken.kind;
|
||||
if (type == ModelicaParser.ANNOTATION) {
|
||||
discardingAnnotation = true;
|
||||
} else if (discardingAnnotation && type == ModelicaParser.SC) {
|
||||
discardingAnnotation = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void analyzeToken(GenericToken currentToken) {
|
||||
skipWithinAndImport((Token) currentToken);
|
||||
skipAnnotation((Token) currentToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isLanguageSpecificDiscarding() {
|
||||
return discardingWithinAndImport || discardingAnnotation;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
import net.sourceforge.pmd.lang.XPathHandler;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
|
||||
import net.sourceforge.pmd.lang.modelica.ast.ASTStoredDefinition;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaSymbolFacade;
|
||||
import net.sourceforge.pmd.lang.modelica.rule.ModelicaRuleViolationFactory;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
public class ModelicaHandler extends AbstractLanguageVersionHandler {
|
||||
@Override
|
||||
public XPathHandler getXPathHandler() {
|
||||
return new DefaultASTXPathHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
return ModelicaRuleViolationFactory.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parser getParser(ParserOptions parserOptions) {
|
||||
return new ModelicaParser(parserOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisitorStarter getSymbolFacade() {
|
||||
return new VisitorStarter() {
|
||||
@Override
|
||||
public void start(Node rootNode) {
|
||||
new ModelicaSymbolFacade().initializeWith((ASTStoredDefinition) rootNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisitorStarter getSymbolFacade(ClassLoader classLoader) {
|
||||
return getSymbolFacade();
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica;
|
||||
|
||||
import net.sourceforge.pmd.lang.BaseLanguageModule;
|
||||
import net.sourceforge.pmd.lang.modelica.rule.ModelicaRuleChainVisitor;
|
||||
|
||||
public class ModelicaLanguageModule extends BaseLanguageModule {
|
||||
public static final String NAME = "Modelica";
|
||||
public static final String TERSE_NAME = "modelica";
|
||||
|
||||
public ModelicaLanguageModule() {
|
||||
super(NAME, null, TERSE_NAME, ModelicaRuleChainVisitor.class, "mo");
|
||||
addVersion("", new ModelicaHandler(), true);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractParser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.TokenManager;
|
||||
import net.sourceforge.pmd.lang.ast.AbstractTokenManager;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.ParseException;
|
||||
import net.sourceforge.pmd.lang.ast.SimpleCharStream;
|
||||
|
||||
|
||||
public class ModelicaParser extends AbstractParser {
|
||||
public ModelicaParser(final ParserOptions parserOptions) {
|
||||
super(parserOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TokenManager createTokenManager(Reader source) {
|
||||
return new ModelicaTokenManager(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canParse() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node parse(String fileName, Reader source) throws ParseException {
|
||||
AbstractTokenManager.setFileName(fileName);
|
||||
return new net.sourceforge.pmd.lang.modelica.ast.ModelicaParser(new SimpleCharStream(source)).StoredDefinition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, String> getSuppressMap() {
|
||||
return new HashMap<Integer, String>(); // TODO
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica;
|
||||
|
||||
import java.io.Reader;
|
||||
|
||||
import net.sourceforge.pmd.lang.TokenManager;
|
||||
import net.sourceforge.pmd.lang.ast.AbstractTokenManager;
|
||||
import net.sourceforge.pmd.lang.ast.SimpleCharStream;
|
||||
import net.sourceforge.pmd.lang.modelica.ast.ModelicaParserTokenManager;
|
||||
|
||||
|
||||
public class ModelicaTokenManager implements TokenManager {
|
||||
private final ModelicaParserTokenManager modelicaParserTokenManager;
|
||||
|
||||
public ModelicaTokenManager(final Reader source) {
|
||||
modelicaParserTokenManager = new ModelicaParserTokenManager(new SimpleCharStream(source));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNextToken() {
|
||||
return modelicaParserTokenManager.getNextToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFileName(String fileName) {
|
||||
AbstractTokenManager.setFileName(fileName);
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassSpecialization;
|
||||
|
||||
public class ASTClassDefinition extends AbstractModelicaNode {
|
||||
private ASTClassPrefixes prefixes;
|
||||
private ModelicaClassSpecialization specialization;
|
||||
private ModelicaClassSpecifierNode specifier;
|
||||
|
||||
public ASTClassDefinition(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public ASTClassDefinition(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
public boolean isPartial() {
|
||||
return prefixes.getFirstChildOfType(ASTPartialClause.class) != null;
|
||||
}
|
||||
|
||||
public boolean isEncapsulated() {
|
||||
return getFirstChildOfType(ASTEncapsulatedClause.class) != null;
|
||||
}
|
||||
|
||||
public ModelicaClassSpecialization getSpecialization() {
|
||||
return specialization;
|
||||
}
|
||||
|
||||
public ModelicaClassSpecifierNode getClassSpecifier() {
|
||||
return specifier;
|
||||
}
|
||||
|
||||
private void checkSpecialization(Class<?> clauseClass, ModelicaClassSpecialization restriction) {
|
||||
if (prefixes.getFirstChildOfType(clauseClass) != null) {
|
||||
assert specialization == null;
|
||||
specialization = restriction;
|
||||
}
|
||||
}
|
||||
|
||||
private void detectSpecialization() {
|
||||
checkSpecialization(ASTClassClause.class, ModelicaClassSpecialization.CLASS);
|
||||
checkSpecialization(ASTModelClause.class, ModelicaClassSpecialization.MODEL);
|
||||
checkSpecialization(ASTRecordClause.class, ModelicaClassSpecialization.RECORD);
|
||||
checkSpecialization(ASTOperatorRecordClause.class, ModelicaClassSpecialization.OPERATOR_RECORD);
|
||||
checkSpecialization(ASTBlockClause.class, ModelicaClassSpecialization.BLOCK);
|
||||
checkSpecialization(ASTConnectorClause.class, ModelicaClassSpecialization.CONNECTOR);
|
||||
checkSpecialization(ASTExpandableConnectorClause.class, ModelicaClassSpecialization.EXPANDABLE_CONNECTOR);
|
||||
checkSpecialization(ASTTypeClause.class, ModelicaClassSpecialization.TYPE);
|
||||
checkSpecialization(ASTPackageClause.class, ModelicaClassSpecialization.PACKAGE);
|
||||
checkSpecialization(ASTOperatorClause.class, ModelicaClassSpecialization.OPERATOR);
|
||||
ASTFunctionClause functionOrNull = prefixes.getFirstChildOfType(ASTFunctionClause.class);
|
||||
if (functionOrNull != null) {
|
||||
boolean isPure = functionOrNull.getFirstChildOfType(ASTPureClause.class) != null;
|
||||
boolean isOperator = functionOrNull.getFirstChildOfType(ASTOperatorClause.class) != null;
|
||||
assert specialization == null;
|
||||
specialization = ModelicaClassSpecialization.getFunctionSpecialization(isPure, isOperator);
|
||||
}
|
||||
assert specialization != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
prefixes = getFirstChildOfType(ASTClassPrefixes.class);
|
||||
specifier = getFirstChildOfType(ASTClassSpecifier.class).getFirstChildOfType(ModelicaClassSpecifierNode.class);
|
||||
detectSpecialization();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.CompositeName;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionState;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolvableEntity;
|
||||
|
||||
public final class ASTComponentReference extends AbstractModelicaNode implements ResolvableModelicaNode {
|
||||
private String[] nameComponentsWithoutSubscripts;
|
||||
private boolean absolute;
|
||||
private ResolutionResult<ResolvableEntity> resolutionCandidates;
|
||||
|
||||
ASTComponentReference(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTComponentReference(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
void markAbsolute() {
|
||||
absolute = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this reference is absolute (starts with a dot), such as
|
||||
* <code>y = .Modelica.Math.cos(x)</code>.
|
||||
*/
|
||||
boolean isAbsolute() {
|
||||
return absolute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link CompositeName} object representing the lexical reference with subscripts being ignored, if any.
|
||||
*/
|
||||
public CompositeName getCompositeNameWithoutSubscripts() {
|
||||
return CompositeName.create(absolute, nameComponentsWithoutSubscripts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns resolution candidates for the referred component (and <b>not</b> dereferencing its type, etc.).
|
||||
*
|
||||
* We do not decide on entity type on behalf of the rule code, since this may introduce false negatives.
|
||||
*/
|
||||
@Override
|
||||
public ResolutionResult<ResolvableEntity> getResolutionCandidates() {
|
||||
if (resolutionCandidates == null) {
|
||||
resolutionCandidates = getMostSpecificScope().safeResolveLexically(ResolvableEntity.class, ResolutionState.forComponentReference(), getCompositeNameWithoutSubscripts());
|
||||
}
|
||||
return resolutionCandidates;
|
||||
}
|
||||
|
||||
// For Rule Designer
|
||||
public String getResolvedTo() {
|
||||
return Helper.getResolvedTo(getResolutionCandidates());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
|
||||
nameComponentsWithoutSubscripts = new String[jjtGetNumChildren()];
|
||||
for (int i = 0; i < nameComponentsWithoutSubscripts.length; ++i) {
|
||||
String name = jjtGetChild(i).getFirstChildOfType(ASTSimpleName.class).getImage();
|
||||
nameComponentsWithoutSubscripts[i] = name;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
public final class ASTDerClassSpecifier extends AbstractModelicaClassSpecifierNode {
|
||||
ASTDerClassSpecifier(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTDerClassSpecifier(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
public class ASTElementList extends AbstractModelicaNode {
|
||||
private Visibility visibility;
|
||||
|
||||
public ASTElementList(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public ASTElementList(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
void setVisibility(Visibility visibility) {
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public Visibility getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
public final class ASTEnumerationShortClassSpecifier extends AbstractModelicaClassSpecifierNode {
|
||||
ASTEnumerationShortClassSpecifier(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTEnumerationShortClassSpecifier(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassType;
|
||||
|
||||
public final class ASTExtendingLongClassSpecifier extends AbstractModelicaClassSpecifierNode {
|
||||
ASTExtendingLongClassSpecifier(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTExtendingLongClassSpecifier(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateExtendsAndImports(ModelicaClassType classTypeDeclaration) {
|
||||
super.populateExtendsAndImports(classTypeDeclaration);
|
||||
pushExtendsAndImports(classTypeDeclaration, getFirstChildOfType(ASTComposition.class));
|
||||
// TODO
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.CompositeName;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.InternalModelicaResolverApi;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaDeclaration;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaScope;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionContext;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionState;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.Watchdog;
|
||||
|
||||
public final class ASTMultipleDefinitionImportClause extends AbstractModelicaImportClause {
|
||||
private ASTName importFrom;
|
||||
private Set<String> importedNames = new HashSet<>();
|
||||
|
||||
ASTMultipleDefinitionImportClause(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTMultipleDefinitionImportClause(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
importFrom = getFirstChildOfType(ASTName.class);
|
||||
ASTImportList importList = getFirstChildOfType(ASTImportList.class);
|
||||
for (int i = 0; i < importList.jjtGetNumChildren(); ++i) {
|
||||
ASTSimpleName namePart = (ASTSimpleName) importList.jjtGetChild(i);
|
||||
importedNames.add(namePart.getImage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResolutionResult<ModelicaDeclaration> getCacheableImportSources(ResolutionState state, ModelicaScope scope) {
|
||||
return scope.safeResolveLexically(ModelicaDeclaration.class, state, importFrom.getCompositeName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fetchImportedClassesFromSource(ResolutionContext result, ModelicaDeclaration source, String simpleName) throws Watchdog.CountdownException {
|
||||
if (importedNames.contains(simpleName)) {
|
||||
InternalModelicaResolverApi.resolveFurtherNameComponents(source, result, CompositeName.create(simpleName));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQualified() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.CompositeName;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionState;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolvableEntity;
|
||||
|
||||
public final class ASTName extends AbstractModelicaNode implements ResolvableModelicaNode {
|
||||
private String[] nameComponents;
|
||||
private ResolutionResult<ResolvableEntity> resolutionCandidates;
|
||||
private boolean absolute = false;
|
||||
|
||||
ASTName(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTName(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < jjtGetNumChildren(); ++i) {
|
||||
if (i != 0 || absolute) {
|
||||
sb.append('.');
|
||||
}
|
||||
sb.append(((ASTSimpleName) jjtGetChild(i)).getImage());
|
||||
}
|
||||
setImage(sb.toString());
|
||||
|
||||
nameComponents = new String[jjtGetNumChildren()];
|
||||
for (int i = 0; i < jjtGetNumChildren(); ++i) {
|
||||
nameComponents[i] = jjtGetChild(i).getImage();
|
||||
}
|
||||
}
|
||||
|
||||
void markAbsolute() {
|
||||
absolute = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this reference is absolute (starts with a dot), such as
|
||||
* <code>.Modelica.Blocks.Continuous.Filter</code>.
|
||||
*/
|
||||
public boolean isAbsolute() {
|
||||
return absolute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link CompositeName} object representing a lexical reference contained in this node.
|
||||
*/
|
||||
public CompositeName getCompositeName() {
|
||||
return CompositeName.create(absolute, nameComponents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns resolution candidates for the referred entity.
|
||||
*
|
||||
* We do not decide on entity type on behalf of the rule code, since this may introduce false negatives.
|
||||
*/
|
||||
@Override
|
||||
public ResolutionResult<ResolvableEntity> getResolutionCandidates() {
|
||||
if (resolutionCandidates == null) {
|
||||
resolutionCandidates = getMostSpecificScope().safeResolveLexically(ResolvableEntity.class, ResolutionState.forType(), getCompositeName());
|
||||
}
|
||||
return resolutionCandidates;
|
||||
}
|
||||
|
||||
// For Rule Designer
|
||||
public String getResolvedTo() {
|
||||
return Helper.getResolvedTo(getResolutionCandidates());
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaDeclaration;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaScope;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionContext;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionState;
|
||||
|
||||
public final class ASTRenamingImportClause extends AbstractModelicaImportClause {
|
||||
private ASTName importWhat;
|
||||
private String renamedTo;
|
||||
|
||||
ASTRenamingImportClause(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTRenamingImportClause(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
|
||||
importWhat = getFirstChildOfType(ASTName.class);
|
||||
renamedTo = getFirstChildOfType(ASTSimpleName.class).getImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResolutionResult<ModelicaDeclaration> getCacheableImportSources(ResolutionState state, ModelicaScope scope) {
|
||||
return scope.safeResolveLexically(ModelicaDeclaration.class, state, importWhat.getCompositeName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fetchImportedClassesFromSource(ResolutionContext result, ModelicaDeclaration source, String simpleName) {
|
||||
if (renamedTo.equals(simpleName)) {
|
||||
result.addCandidate(source);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQualified() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassType;
|
||||
|
||||
public final class ASTSimpleLongClassSpecifier extends AbstractModelicaClassSpecifierNode {
|
||||
ASTSimpleLongClassSpecifier(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTSimpleLongClassSpecifier(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
void populateExtendsAndImports(ModelicaClassType classTypeDeclaration) {
|
||||
super.populateExtendsAndImports(classTypeDeclaration);
|
||||
pushExtendsAndImports(classTypeDeclaration, getFirstChildOfType(ASTComposition.class));
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.InternalModelicaResolverApi;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassType;
|
||||
|
||||
public final class ASTSimpleShortClassSpecifier extends AbstractModelicaClassSpecifierNode {
|
||||
ASTSimpleShortClassSpecifier(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTSimpleShortClassSpecifier(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateExtendsAndImports(ModelicaClassType classTypeDeclaration) {
|
||||
super.populateExtendsAndImports(classTypeDeclaration);
|
||||
InternalModelicaResolverApi.addExtendToClass(
|
||||
classTypeDeclaration,
|
||||
Visibility.UNSPEC,
|
||||
getFirstChildOfType(ASTName.class).getCompositeName()
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaDeclaration;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaScope;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionContext;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionState;
|
||||
|
||||
public class ASTSingleDefinitionImportClause extends AbstractModelicaImportClause {
|
||||
private ASTName importWhat;
|
||||
private String importedName;
|
||||
|
||||
ASTSingleDefinitionImportClause(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTSingleDefinitionImportClause(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
|
||||
importWhat = getFirstChildOfType(ASTName.class);
|
||||
importedName = importWhat.jjtGetChild(importWhat.jjtGetNumChildren() - 1).getImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResolutionResult<ModelicaDeclaration> getCacheableImportSources(ResolutionState state, ModelicaScope scope) {
|
||||
return scope.safeResolveLexically(ModelicaDeclaration.class, state, importWhat.getCompositeName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fetchImportedClassesFromSource(ResolutionContext result, ModelicaDeclaration source, String simpleName) {
|
||||
if (importedName.equals(simpleName)) {
|
||||
result.addCandidate(source);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQualified() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.CompositeName;
|
||||
|
||||
/**
|
||||
* A representation of a Modelica source code file.
|
||||
*/
|
||||
public class ASTStoredDefinition extends AbstractModelicaNode {
|
||||
private boolean hasBOM = false;
|
||||
|
||||
ASTStoredDefinition(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTStoredDefinition(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
void markHasBOM() {
|
||||
hasBOM = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this source file contains Byte Order Mark.
|
||||
*/
|
||||
public boolean getHasBOM() {
|
||||
return hasBOM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < jjtGetNumChildren(); ++i) {
|
||||
AbstractModelicaNode child = (AbstractModelicaNode) jjtGetChild(i);
|
||||
if (child instanceof ASTWithinClause) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(CompositeName.NAME_COMPONENT_SEPARATOR);
|
||||
}
|
||||
sb.append(child.getImage());
|
||||
}
|
||||
}
|
||||
setImage(sb.toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.CompositeName;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.InternalModelicaResolverApi;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaDeclaration;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaScope;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionContext;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionState;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.Watchdog;
|
||||
|
||||
public final class ASTUnqualifiedImportClause extends AbstractModelicaImportClause {
|
||||
private ASTName importFromWhere;
|
||||
|
||||
ASTUnqualifiedImportClause(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTUnqualifiedImportClause(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
|
||||
importFromWhere = getFirstChildOfType(ASTName.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResolutionResult<ModelicaDeclaration> getCacheableImportSources(ResolutionState state, ModelicaScope scope) {
|
||||
return scope.safeResolveLexically(ModelicaDeclaration.class, state, importFromWhere.getCompositeName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fetchImportedClassesFromSource(ResolutionContext result, ModelicaDeclaration source, String simpleName) throws Watchdog.CountdownException {
|
||||
result.watchdogTick();
|
||||
InternalModelicaResolverApi.resolveFurtherNameComponents(source, result, CompositeName.create(simpleName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQualified() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
public final class ASTWithinClause extends AbstractModelicaNode {
|
||||
ASTWithinClause(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTWithinClause(ModelicaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(ModelicaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
|
||||
ASTName name = getFirstChildOfType(ASTName.class);
|
||||
if (name != null) {
|
||||
setImage(name.getImage());
|
||||
} else {
|
||||
setImage("");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.InternalModelicaResolverApi;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassType;
|
||||
|
||||
/**
|
||||
* Common parent for class-specifier nodes, see {@link ModelicaClassSpecifierNode} for public API.
|
||||
*/
|
||||
abstract class AbstractModelicaClassSpecifierNode extends AbstractModelicaNode implements ModelicaClassSpecifierNode {
|
||||
AbstractModelicaClassSpecifierNode(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
AbstractModelicaClassSpecifierNode(ModelicaParser parser, int id) {
|
||||
super(parser, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
super.jjtClose();
|
||||
setImage(getFirstChildOfType(ASTSimpleName.class).getImage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in the class definition with <code>extends</code> and <code>import</code> clauses contained in this AST node.
|
||||
*
|
||||
* @param classTypeDeclaration a class declaration object corresponding to this AST node
|
||||
*/
|
||||
void populateExtendsAndImports(ModelicaClassType classTypeDeclaration) {
|
||||
// by default, do nothing
|
||||
}
|
||||
|
||||
private void pushExtendsAndImportsFromList(ModelicaClassType classTypeDeclaration, ASTElementList listNode) {
|
||||
for (int i = 0; i < listNode.jjtGetNumChildren(); ++i) {
|
||||
AbstractModelicaNode child = (AbstractModelicaNode) listNode.jjtGetChild(i);
|
||||
if (child instanceof ASTExtendsClause) {
|
||||
InternalModelicaResolverApi.addExtendToClass(
|
||||
classTypeDeclaration,
|
||||
listNode.getVisibility(),
|
||||
child.getFirstChildOfType(ASTName.class).getCompositeName()
|
||||
);
|
||||
}
|
||||
if (child instanceof ASTImportClause) {
|
||||
InternalModelicaResolverApi.addImportToClass(
|
||||
classTypeDeclaration,
|
||||
listNode.getVisibility(),
|
||||
child.getFirstChildOfType(ModelicaImportClause.class)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pushExtendsAndImports(ModelicaClassType classTypeDeclaration, ASTComposition composition) {
|
||||
for (int i = 0; i < composition.jjtGetNumChildren(); ++i) {
|
||||
ModelicaNode maybeElementList = composition.jjtGetChild(i);
|
||||
if (maybeElementList instanceof ASTElementList) {
|
||||
pushExtendsAndImportsFromList(classTypeDeclaration, (ASTElementList) maybeElementList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSimpleClassName() {
|
||||
return getImage();
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaDeclaration;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaScope;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionContext;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionState;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.Watchdog;
|
||||
|
||||
/**
|
||||
* Common internal machinery for various import clauses to describe themselves to resolver.
|
||||
*/
|
||||
abstract class AbstractModelicaImportClause extends AbstractModelicaNode implements ModelicaImportClause {
|
||||
private ResolutionResult<ModelicaDeclaration> importSourcesCache;
|
||||
|
||||
AbstractModelicaImportClause(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
AbstractModelicaImportClause(ModelicaParser parser, int id) {
|
||||
super(parser, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some import clauses are considered "qualified", some "unqualified", the former being processed first
|
||||
* while looking up some name. See "5.3.1 Simple Name Lookup" from MLS 3.4.
|
||||
*
|
||||
* @return Whether this kind of import is considered "qualified"
|
||||
*/
|
||||
abstract boolean isQualified();
|
||||
|
||||
/**
|
||||
* A template method to be used by {@link resolveSimpleName}. Usually used to fetch the lexically referenced
|
||||
* class in the corresponding import statement.
|
||||
*/
|
||||
protected abstract ResolutionResult<ModelicaDeclaration> getCacheableImportSources(ResolutionState state, ModelicaScope scope);
|
||||
|
||||
/**
|
||||
* A template method to be used by {@link resolveSimpleName}. Usually used to try to fetch declarations for
|
||||
* <code>simpleName</code> from particular <i>source</i> returned by {@link getCacheableImportSources}.
|
||||
*/
|
||||
protected abstract void fetchImportedClassesFromSource(ResolutionContext result, ModelicaDeclaration source, String simpleName) throws Watchdog.CountdownException;
|
||||
|
||||
/**
|
||||
* Tries to resolve the specified name via this import clause.
|
||||
*
|
||||
* @param result Resolution context
|
||||
* @param simpleName Name to resolve
|
||||
* @throws Watchdog.CountdownException if too many resolution steps were performed
|
||||
*/
|
||||
final void resolveSimpleName(ResolutionContext result, String simpleName) throws Watchdog.CountdownException {
|
||||
// No need to re-resolve if already resolved successfully
|
||||
if (importSourcesCache == null || importSourcesCache.wasTimedOut()) {
|
||||
importSourcesCache = getCacheableImportSources(result.getState(), getMostSpecificScope().getParent());
|
||||
}
|
||||
for (ModelicaDeclaration source : importSourcesCache.getBestCandidates()) {
|
||||
fetchImportedClassesFromSource(result, source, simpleName);
|
||||
}
|
||||
result.markHidingPoint();
|
||||
for (ModelicaDeclaration source : importSourcesCache.getHiddenCandidates()) {
|
||||
fetchImportedClassesFromSource(result, source, simpleName);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.modelica.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.AbstractNode;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaScope;
|
||||
|
||||
/**
|
||||
* Abstract base class for all nodes parsed by {@link ModelicaParser}.
|
||||
*
|
||||
* Please note that some of these nodes are autogenerated and placed to
|
||||
* <code>pmd-modelica/target/generated-sources/javacc</code> by the build script. Those
|
||||
* located here are deleted from autogenerated sources after build.
|
||||
*
|
||||
* @see ModelicaNode for public API.
|
||||
*/
|
||||
abstract class AbstractModelicaNode extends AbstractNode implements Node, ModelicaNode {
|
||||
private ModelicaParser parser;
|
||||
private ModelicaScope ownScope;
|
||||
|
||||
AbstractModelicaNode(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
AbstractModelicaNode(ModelicaParser parser, int id) {
|
||||
super(id);
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Object jjtAccept(ModelicaParserVisitor visitor, Object data);
|
||||
|
||||
@Override
|
||||
public String getXPathNodeName() {
|
||||
return getClass().getSimpleName().substring(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelicaNode jjtGetParent() {
|
||||
return (ModelicaNode) super.jjtGetParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelicaNode jjtGetChild(int index) {
|
||||
return (ModelicaNode) super.jjtGetChild(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtOpen() {
|
||||
if (beginLine == -1 && parser.token.next != null) {
|
||||
beginLine = parser.token.next.beginLine;
|
||||
beginColumn = parser.token.next.beginColumn;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jjtClose() {
|
||||
if (beginLine == -1 && (children == null || children.length == 0)) {
|
||||
beginColumn = parser.token.beginColumn;
|
||||
}
|
||||
if (beginLine == -1) {
|
||||
beginLine = parser.token.beginLine;
|
||||
}
|
||||
endLine = parser.token.endLine;
|
||||
endColumn = parser.token.endColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelicaScope getContainingScope() {
|
||||
return ((AbstractModelicaNode) parent).getMostSpecificScope();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelicaScope getMostSpecificScope() {
|
||||
if (ownScope == null) {
|
||||
return getContainingScope();
|
||||
} else {
|
||||
return ownScope;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For resolver, set the lexical scope defined by this node, if any.
|
||||
*
|
||||
* @param scope Scope defined by this specific node
|
||||
*/
|
||||
void setOwnScope(ModelicaScope scope) {
|
||||
ownScope = scope;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user