-
Notifications
You must be signed in to change notification settings - Fork 259
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
81e8f30
commit 6b45890
Showing
28 changed files
with
1,571 additions
and
1,858 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. | ||
* | ||
* Licensed 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 | ||
* | ||
* https://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 org.pkl.lsp.analyzers | ||
|
||
import org.pkl.lsp.ast.Node | ||
|
||
/** | ||
* Scans the source tree, and builds [PklDiagnostic]s. | ||
* | ||
* Diagnostics then get reported back to the user. | ||
*/ | ||
abstract class Analyzer { | ||
fun annotate(node: Node, diagnosticsHolder: MutableList<PklDiagnostic>) { | ||
if (doAnnotate(node, diagnosticsHolder)) { | ||
return | ||
} | ||
node.children.forEach { annotate(it, diagnosticsHolder) } | ||
} | ||
|
||
/** | ||
* Collect diagnostics, pushing them into [diagnosticsHolder] as they are captured. | ||
* | ||
* Return `false` if the annotator does not need to analyze any further. This skips calling | ||
* [doAnnotate] on its children. | ||
*/ | ||
protected abstract fun doAnnotate( | ||
node: Node, | ||
diagnosticsHolder: MutableList<PklDiagnostic> | ||
): Boolean | ||
} |
121 changes: 121 additions & 0 deletions
121
pkl-lsp/src/main/kotlin/org/pkl/lsp/analyzers/ModifierAnalyzer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/** | ||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. | ||
* | ||
* Licensed 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 | ||
* | ||
* https://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 org.pkl.lsp.analyzers | ||
|
||
import org.eclipse.lsp4j.DiagnosticSeverity | ||
import org.pkl.lsp.ErrorMessages | ||
import org.pkl.lsp.PklLSPServer | ||
import org.pkl.lsp.ast.* | ||
import org.pkl.lsp.ast.TokenType.* | ||
|
||
class ModifierAnalyzer(private val server: PklLSPServer) : Analyzer() { | ||
companion object { | ||
private val MODULE_MODIFIERS = setOf(ABSTRACT, OPEN) | ||
private val AMENDING_MODULE_MODIFIERS = emptySet<TokenType>() | ||
private val CLASS_MODIFIERS = setOf(ABSTRACT, OPEN, EXTERNAL, LOCAL) | ||
private val TYPE_ALIAS_MODIFIERS = setOf(EXTERNAL, LOCAL) | ||
private val CLASS_METHOD_MODIFIERS = setOf(ABSTRACT, EXTERNAL, LOCAL, CONST) | ||
private val CLASS_PROPERTY_MODIFIERS = setOf(ABSTRACT, EXTERNAL, HIDDEN, LOCAL, FIXED, CONST) | ||
private val OBJECT_METHOD_MODIFIERS = setOf(LOCAL) | ||
private val OBJECT_PROPERTY_MODIFIERS = setOf(LOCAL) | ||
} | ||
|
||
override fun doAnnotate(node: Node, diagnosticsHolder: MutableList<PklDiagnostic>): Boolean { | ||
if (node !is ModifierListOwner || node.modifiers == null) { | ||
return false | ||
} | ||
|
||
var localModifier: Node? = null | ||
var abstractModifier: Node? = null | ||
var openModifier: Node? = null | ||
var hiddenModifier: Node? = null | ||
var fixedModifier: Node? = null | ||
|
||
for (modifier in node.modifiers!!) { | ||
when (modifier.type) { | ||
LOCAL -> localModifier = modifier | ||
ABSTRACT -> abstractModifier = modifier | ||
OPEN -> openModifier = modifier | ||
HIDDEN -> hiddenModifier = modifier | ||
FIXED -> fixedModifier = modifier | ||
else -> {} | ||
} | ||
} | ||
if (localModifier == null) { | ||
when (node) { | ||
is ClassProperty -> { | ||
if ( | ||
node.parent is Module && | ||
(node.parent as Module).isAmend && | ||
(hiddenModifier != null || node.typeAnnotation != null) | ||
) { | ||
if (node.identifier != null) { | ||
diagnosticsHolder.add( | ||
PklDiagnostic( | ||
node.identifier!!, | ||
ErrorMessages.create("missingModifierLocal"), | ||
DiagnosticSeverity.Error | ||
) | ||
) | ||
return true | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (abstractModifier != null && openModifier != null) { | ||
diagnosticsHolder.add( | ||
PklDiagnostic( | ||
abstractModifier, | ||
ErrorMessages.create("modifierAbstractConflictsWithOpen"), | ||
DiagnosticSeverity.Error | ||
) | ||
) | ||
diagnosticsHolder.add( | ||
PklDiagnostic( | ||
openModifier, | ||
ErrorMessages.create("modifierOpenConflictsWithAbstract"), | ||
DiagnosticSeverity.Error | ||
) | ||
) | ||
} | ||
|
||
val (description, applicableModifiers) = | ||
when (node) { | ||
is ModuleDeclaration -> | ||
if (node.isAmend) "amending modules" to AMENDING_MODULE_MODIFIERS | ||
else "modules" to MODULE_MODIFIERS | ||
is Class -> "classes" to CLASS_MODIFIERS | ||
is TypeAlias -> "typealiases" to TYPE_ALIAS_MODIFIERS | ||
is ClassMethod -> "class methods" to CLASS_METHOD_MODIFIERS | ||
is ClassProperty -> "class properties" to CLASS_PROPERTY_MODIFIERS | ||
else -> return false | ||
} | ||
for (modifier in node.modifiers!!) { | ||
if (modifier.type !in applicableModifiers) { | ||
diagnosticsHolder.add( | ||
PklDiagnostic( | ||
modifier, | ||
ErrorMessages.create("modifierIsNotApplicable", modifier.text, description), | ||
DiagnosticSeverity.Error | ||
) | ||
) | ||
} | ||
} | ||
return false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.