-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes partially #543 ### Summary of Changes Show an info if * `@PythonName` is identical to the Safe-DS name of a declaration, * `@PythonModule` is identical to the Safe-DS package. In those cases, the annotations could be removed. --------- Co-authored-by: megalinter-bot <[email protected]>
- Loading branch information
1 parent
38d1181
commit 5a9dcbb
Showing
14 changed files
with
243 additions
and
69 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,102 @@ | ||
import { isSdsAnnotation, SdsAnnotatedObject, SdsAnnotation, SdsParameter } from '../generated/ast.js'; | ||
import { annotationCallsOrEmpty } from '../helpers/nodeProperties.js'; | ||
import { isSdsAnnotation, SdsAnnotatedObject, SdsAnnotation, SdsModule, SdsParameter } from '../generated/ast.js'; | ||
import { argumentsOrEmpty, findFirstAnnotationCallOf, hasAnnotationCallOf } from '../helpers/nodeProperties.js'; | ||
import { SafeDsModuleMembers } from './safe-ds-module-members.js'; | ||
import { resourceNameToUri } from '../../helpers/resources.js'; | ||
import { URI } from 'langium'; | ||
import { SafeDsServices } from '../safe-ds-module.js'; | ||
import { SafeDsNodeMapper } from '../helpers/safe-ds-node-mapper.js'; | ||
import { toConstantExpressionOrUndefined } from '../partialEvaluation/toConstantExpressionOrUndefined.js'; | ||
import { SdsConstantExpression, SdsConstantString } from '../partialEvaluation/model.js'; | ||
|
||
const ANNOTATION_USAGE_URI = resourceNameToUri('builtins/safeds/lang/annotationUsage.sdsstub'); | ||
const CODE_GENERATION_URI = resourceNameToUri('builtins/safeds/lang/codeGeneration.sdsstub'); | ||
const IDE_INTEGRATION_URI = resourceNameToUri('builtins/safeds/lang/ideIntegration.sdsstub'); | ||
const MATURITY_URI = resourceNameToUri('builtins/safeds/lang/maturity.sdsstub'); | ||
|
||
export class SafeDsAnnotations extends SafeDsModuleMembers<SdsAnnotation> { | ||
private readonly nodeMapper: SafeDsNodeMapper; | ||
|
||
constructor(services: SafeDsServices) { | ||
super(services); | ||
|
||
this.nodeMapper = services.helpers.NodeMapper; | ||
} | ||
|
||
isDeprecated(node: SdsAnnotatedObject | undefined): boolean { | ||
return this.hasAnnotationCallOf(node, this.Deprecated); | ||
return hasAnnotationCallOf(node, this.Deprecated); | ||
} | ||
|
||
private get Deprecated(): SdsAnnotation | undefined { | ||
return this.getAnnotation(MATURITY_URI, 'Deprecated'); | ||
} | ||
|
||
isExperimental(node: SdsAnnotatedObject | undefined): boolean { | ||
return this.hasAnnotationCallOf(node, this.Experimental); | ||
return hasAnnotationCallOf(node, this.Experimental); | ||
} | ||
|
||
private get Experimental(): SdsAnnotation | undefined { | ||
return this.getAnnotation(MATURITY_URI, 'Experimental'); | ||
} | ||
|
||
isExpert(node: SdsParameter | undefined): boolean { | ||
return this.hasAnnotationCallOf(node, this.Expert); | ||
return hasAnnotationCallOf(node, this.Expert); | ||
} | ||
|
||
private get Expert(): SdsAnnotation | undefined { | ||
return this.getAnnotation(IDE_INTEGRATION_URI, 'Expert'); | ||
} | ||
|
||
getPythonModule(node: SdsModule | undefined): string | undefined { | ||
const value = this.getArgumentValue(node, this.PythonModule, 'qualifiedName'); | ||
if (value instanceof SdsConstantString) { | ||
return value.value; | ||
} else { | ||
return undefined; | ||
} | ||
} | ||
|
||
get PythonModule(): SdsAnnotation | undefined { | ||
return this.getAnnotation(CODE_GENERATION_URI, 'PythonModule'); | ||
} | ||
|
||
getPythonName(node: SdsAnnotatedObject | undefined): string | undefined { | ||
const value = this.getArgumentValue(node, this.PythonName, 'name'); | ||
if (value instanceof SdsConstantString) { | ||
return value.value; | ||
} else { | ||
return undefined; | ||
} | ||
} | ||
|
||
get PythonName(): SdsAnnotation | undefined { | ||
return this.getAnnotation(CODE_GENERATION_URI, 'PythonName'); | ||
} | ||
|
||
isRepeatable(node: SdsAnnotation | undefined): boolean { | ||
return this.hasAnnotationCallOf(node, this.Repeatable); | ||
return hasAnnotationCallOf(node, this.Repeatable); | ||
} | ||
|
||
private get Repeatable(): SdsAnnotation | undefined { | ||
return this.getAnnotation(ANNOTATION_USAGE_URI, 'Repeatable'); | ||
} | ||
|
||
private hasAnnotationCallOf(node: SdsAnnotatedObject | undefined, expected: SdsAnnotation | undefined): boolean { | ||
return annotationCallsOrEmpty(node).some((it) => { | ||
const actual = it.annotation?.ref; | ||
return actual === expected; | ||
}); | ||
} | ||
|
||
private getAnnotation(uri: URI, name: string): SdsAnnotation | undefined { | ||
return this.getModuleMember(uri, name, isSdsAnnotation); | ||
} | ||
|
||
/** | ||
* Finds the first call of the given annotation on the given node and returns the value that is assigned to the | ||
* parameter with the given name. | ||
*/ | ||
private getArgumentValue( | ||
node: SdsAnnotatedObject | undefined, | ||
annotation: SdsAnnotation | undefined, | ||
parameterName: string, | ||
): SdsConstantExpression | undefined { | ||
const annotationCall = findFirstAnnotationCallOf(node, annotation); | ||
const expression = argumentsOrEmpty(annotationCall).find( | ||
(it) => this.nodeMapper.argumentToParameterOrUndefined(it)?.name === parameterName, | ||
)?.value; | ||
return toConstantExpressionOrUndefined(expression); | ||
} | ||
} |
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.