or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-nodes.mdcpd.mdindex.mdlanguage-parsing.mdrule-development.mdvisitor-pattern.md

language-parsing.mddocs/

0

# Language Module and Parsing

1

2

Core language registration and parsing infrastructure that integrates Scala with PMD's analysis framework. This module handles Scala version management, dialect configuration, and source code parsing using Scalameta.

3

4

## Capabilities

5

6

### Language Module Registration

7

8

Registers Scala language support with PMD framework and manages multiple Scala versions through dialect configuration.

9

10

```java { .api }

11

/**

12

* Language Module for Scala that registers with PMD's language system

13

*/

14

public class ScalaLanguageModule extends BaseLanguageModule {

15

/** The language name: "Scala" */

16

public static final String NAME = "Scala";

17

18

/** The terse name: "scala" */

19

public static final String TERSE_NAME = "scala";

20

21

/**

22

* Create a new instance of Scala Language Module.

23

* Automatically registers support for Scala versions 2.10, 2.11, 2.12, and 2.13

24

* with 2.13 as the default version.

25

*/

26

public ScalaLanguageModule();

27

}

28

```

29

30

**Usage Examples:**

31

32

```java

33

import net.sourceforge.pmd.lang.Language;

34

import net.sourceforge.pmd.lang.LanguageRegistry;

35

import net.sourceforge.pmd.lang.LanguageVersion;

36

import net.sourceforge.pmd.lang.scala.ScalaLanguageModule;

37

38

// Language module is automatically registered via SPI

39

// Located in META-INF/services/net.sourceforge.pmd.lang.Language

40

41

// Access registered language

42

Language scalaLang = LanguageRegistry.getLanguage(ScalaLanguageModule.NAME);

43

LanguageVersion defaultVersion = scalaLang.getDefaultVersion(); // Scala 2.13

44

LanguageVersion scala212 = scalaLang.getVersion("2.12");

45

```

46

47

### Language Version Handler

48

49

Manages Scala dialect-specific parsing and rule processing for different Scala versions.

50

51

```java { .api }

52

/**

53

* The Scala Language Handler implementation for version-specific operations

54

*/

55

public class ScalaLanguageHandler extends AbstractLanguageVersionHandler {

56

/**

57

* Create the Language Handler using the given Scala Dialect

58

* @param scalaDialect the language version to use while parsing

59

*/

60

public ScalaLanguageHandler(Dialect scalaDialect);

61

62

/**

63

* Get the Scala Dialect used in this language version choice

64

* @return the Scala Dialect for this handler

65

*/

66

public Dialect getDialect();

67

68

/**

69

* Get the rule violation factory for creating rule violations

70

* @return ScalaRuleViolationFactory instance

71

*/

72

@Override

73

public RuleViolationFactory getRuleViolationFactory();

74

75

/**

76

* Create a parser instance for the given options

77

* @param parserOptions parsing configuration options

78

* @return ScalaParser configured with this handler's dialect

79

*/

80

@Override

81

public ScalaParser getParser(ParserOptions parserOptions);

82

}

83

```

84

85

**Usage Examples:**

86

87

```java

88

import scala.meta.Dialect;

89

import scala.meta.dialects.package$;

90

91

// Create handler for specific Scala version

92

Dialect scala212 = package$.MODULE$.Scala212();

93

ScalaLanguageHandler handler = new ScalaLanguageHandler(scala212);

94

95

// Get parser for this version

96

ParserOptions options = new ParserOptions();

97

ScalaParser parser = handler.getParser(options);

98

99

// Access dialect information

100

Dialect currentDialect = handler.getDialect();

101

```

102

103

### Scala Source Parser

104

105

Parses Scala source code into PMD-compatible AST using Scalameta parsing technology.

106

107

```java { .api }

108

/**

109

* Scala's Parser implementation. Defers parsing to the scala compiler via

110

* Scalameta. This parser then wraps all of ScalaMeta's Nodes in Java versions

111

* for compatibility.

112

*/

113

public class ScalaParser extends AbstractParser {

114

/**

115

* Create a parser using the given Scala Dialect and set of parser options

116

* @param scalaDialect the Scala Dialect for this parser

117

* @param parserOptions any additional options for this parser

118

*/

119

public ScalaParser(Dialect scalaDialect, ParserOptions parserOptions);

120

121

/**

122

* Check if this parser can parse source code

123

* @return true, always returns true for Scala parser

124

*/

125

@Override

126

public boolean canParse();

127

128

/**

129

* Parse Scala source code into PMD AST

130

* @param fileName the name of the source file

131

* @param source reader providing the source code

132

* @return ASTSource representing the parsed Scala AST

133

* @throws ParseException if parsing fails

134

*/

135

@Override

136

public ASTSource parse(String fileName, Reader source) throws ParseException;

137

138

/**

139

* Get suppression map for ignoring warnings/errors

140

* @return empty map (not currently implemented)

141

*/

142

@Override

143

public Map<Integer, String> getSuppressMap();

144

145

/**

146

* Create token manager for source code

147

* @param source source code reader

148

* @return null (not used by Scala parser)

149

*/

150

@Override

151

protected TokenManager createTokenManager(Reader source);

152

}

153

```

154

155

**Usage Examples:**

156

157

```java

158

import net.sourceforge.pmd.lang.scala.ScalaParser;

159

import net.sourceforge.pmd.lang.scala.ast.ASTSource;

160

import java.io.StringReader;

161

162

// Create parser with Scala 2.12 dialect

163

Dialect scala212 = scala.meta.dialects.package$.MODULE$.Scala212();

164

ParserOptions options = new ParserOptions();

165

ScalaParser parser = new ScalaParser(scala212, options);

166

167

// Parse Scala source code

168

String scalaCode = """

169

object HelloWorld {

170

def main(args: Array[String]): Unit = {

171

println("Hello, World!")

172

}

173

}

174

""";

175

176

try (StringReader reader = new StringReader(scalaCode)) {

177

ASTSource ast = parser.parse("HelloWorld.scala", reader);

178

179

// AST is now ready for analysis

180

System.out.println("Parsed successfully: " + ast.getClass().getSimpleName());

181

} catch (ParseException e) {

182

System.err.println("Parse error: " + e.getMessage());

183

}

184

```

185

186

### AST Tree Builder

187

188

Converts Scalameta AST to PMD-compatible node hierarchy with proper parent-child relationships.

189

190

```java { .api }

191

/**

192

* Translates Scala's AST to a PMD-compatible AST

193

* @InternalApi - Not intended for direct use

194

*/

195

class ScalaTreeBuilder {

196

/**

197

* Construct a matching tree that implements the PMD Node interface

198

* @param <T> the scala node that extends the Tree trait

199

* @param astNode the Java node that extends the PMD Node interface

200

* @return a PMD compatible node representing the Scala AST node

201

*/

202

<T extends Tree> ScalaNode<T> build(T astNode);

203

}

204

```

205

206

## Error Handling

207

208

The parsing system handles errors through PMD's standard exception hierarchy:

209

210

```java { .api }

211

// Main parsing exception

212

public class ParseException extends Exception {

213

public ParseException(String message);

214

public ParseException(Throwable cause);

215

}

216

217

// Token manager errors from Scalameta

218

public class TokenMgrError extends Error {

219

public TokenMgrError(int line, int column, String filename, String message, Throwable cause);

220

}

221

```

222

223

**Common Error Scenarios:**

224

225

```java

226

try {

227

ASTSource ast = parser.parse("test.scala", sourceReader);

228

} catch (ParseException e) {

229

// Handle syntax errors, I/O errors, etc.

230

if (e.getCause() instanceof IOException) {

231

// I/O problem reading source

232

} else {

233

// Syntax error in Scala code

234

}

235

} catch (TokenMgrError e) {

236

// Low-level tokenization error from Scalameta

237

System.err.println("Tokenization failed at line " + e.getLine());

238

}

239

```

240

241

## Supported Scala Versions

242

243

The language module supports multiple Scala versions through Scalameta dialects:

244

245

- **Scala 2.10**: `scala.meta.dialects.package$.MODULE$.Scala210()`

246

- **Scala 2.11**: `scala.meta.dialects.package$.MODULE$.Scala211()`

247

- **Scala 2.12**: `scala.meta.dialects.package$.MODULE$.Scala212()` (default for this package)

248

- **Scala 2.13**: `scala.meta.dialects.package$.MODULE$.Scala213()` (default overall)

249

250

**Version Selection:**

251

252

```java

253

// Through language registry

254

LanguageVersion version = LanguageRegistry.getLanguage(ScalaLanguageModule.NAME)

255

.getVersion("2.12");

256

ScalaLanguageHandler handler = (ScalaLanguageHandler) version.getLanguageVersionHandler();

257

258

// Direct dialect creation

259

Dialect scala212 = scala.meta.dialects.package$.MODULE$.Scala212();

260

ScalaLanguageHandler directHandler = new ScalaLanguageHandler(scala212);

261

```