blob: 85f0223a2f051e7862f99bef21078813c12ac8a5 [file] [log] [blame]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart' as ast;
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/ast.dart' as ast;
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/macro/api/code.dart';
import 'package:analyzer/src/macro/api/macro.dart';
class ClassDeclarationBuilderImpl extends DeclarationBuilderImpl
implements ClassDeclarationBuilder {
final DeclarationCollector _collector;
final ast.ClassDeclarationImpl node;
ClassDeclarationBuilderImpl(this._collector, this.node);
@override
void addToClass(Declaration declaration) {
// TODO(scheglov) feature set
// TODO(scheglov) throw if errors?
var parseResult = parseString(
content: 'class ${node.name.name} { $declaration }',
);
var parsedDeclarations = parseResult.unit.declarations;
var parsedClass = parsedDeclarations.single as ast.ClassDeclaration;
var parsedMember = parsedClass.members.single;
_resetOffsets(parsedMember);
node.members.add(parsedMember);
_collector._add(parsedMember, declaration);
}
/// We parsed [node] in the context of some synthetic code string, its
/// current offsets are meaningless. So, we reset them for now.
static void _resetOffsets(ast.AstNode node) {
for (Token? t = node.beginToken;
t != null && t != node.endToken;
t = t.next) {
t.offset = -1;
}
}
}
class DeclarationBuilderImpl implements DeclarationBuilder {
@override
void addToLibrary(Declaration declaration) {
// TODO: implement addToLibrary
}
@override
Code typeAnnotationCode(ast.TypeAnnotation node) {
return Fragment(node.toSource());
}
}
class DeclarationCollector {
final Map<ast.AstNode, _CollectedDeclaration> _declarations = {};
int _nextId = 0;
/// Elements for nodes in [_declarations] were built.
/// Move information from [_CollectedDeclaration] into elements.
void updateElements() {
for (var entry in _declarations.entries) {
var node = entry.key;
if (node is ast.Declaration) {
var element = node.declaredElement;
if (element is HasElementMacro) {
(element as HasElementMacro).macro = ElementMacro(
entry.value.id,
entry.value.declaration.code,
);
}
}
}
}
void _add(ast.AstNode node, Declaration declaration) {
_declarations[node] = _CollectedDeclaration(_nextId++, declaration);
}
}
class _CollectedDeclaration {
final int id;
final Declaration declaration;
_CollectedDeclaration(this.id, this.declaration);
}