Skip to content

Commit

Permalink
Version 3.6.0-1.0.dev
Browse files Browse the repository at this point in the history
Merge 2f80ad6 into dev
  • Loading branch information
Dart CI committed Jul 3, 2024
2 parents 68053e5 + 2f80ad6 commit be229e0
Show file tree
Hide file tree
Showing 28 changed files with 921 additions and 204 deletions.
5 changes: 4 additions & 1 deletion build/config/BUILDCONFIG.gn
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,10 @@ if (is_win) {
"//build/config/win:winver",
]
if (is_clang) {
_native_compiler_configs += [ "//build/config/win:relative_paths" ]
_native_compiler_configs += [
"//build/config/win:relative_paths",
"//build/config/win:deterministic_builds",
]
}
}
if (is_posix) {
Expand Down
28 changes: 28 additions & 0 deletions build/config/win/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,31 @@ config("relative_paths") {
"-no-canonical-prefixes",
]
}

if (is_clang) {
build_timestamp =
exec_script("//tools/make_coff_timestamp.py", [], "trim string")
}

config("deterministic_builds") {
if (is_clang) {
# /Brepro lets the compiler not write the mtime field in the .obj output.
# link.exe /incremental relies on this field to work correctly, but lld
# never looks at this timestamp, so it's safe to pass this flag with
# lld and get more deterministic compiler output in return.
# In LTO builds, the compiler doesn't write .obj files containing mtimes,
# so /Brepro is ignored there.
cflags = [ "/Brepro" ]

# lld defaults to writing the current time in the pe/coff header.
# For build reproducibility, pass an explicit timestamp. See
# build/compute_build_timestamp.py for how the timestamp is chosen.
# (link.exe also writes the current time, but it doesn't have a flag to
# override that behavior.)
ldflags = [ "/TIMESTAMP:" + build_timestamp ]

# Use a fake fixed base directory for paths in the pdb to make the pdb
# output fully deterministic and independent of the build directory.
ldflags += [ "/PDBSourcePath:o:\fake\prefix" ]
}
}
15 changes: 12 additions & 3 deletions build/toolchain/win/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,18 @@ template("msvc_toolchain") {
]
}

if (is_clang) {
prefix = rebase_path("$clang_base_path/bin", root_build_dir)
lib = "$prefix/lld-link.exe /lib"
link = "$prefix/lld-link.exe"
} else {
lib = "lib.exe"
link = "link.exe"
}

tool("alink") {
rspfile = "{{output}}.rsp"
command = "$python_path $tool_wrapper_path link-wrapper $env False lib.exe /nologo /ignore:4221 /OUT:{{output}} @$rspfile"
command = "$python_path $tool_wrapper_path link-wrapper $env False $lib /nologo /ignore:4221 /OUT:{{output}} @$rspfile"
description = "LIB {{output}}"
outputs = [
# Ignore {{output_extension}} and always use .lib, there's no reason to
Expand All @@ -163,7 +172,7 @@ template("msvc_toolchain") {
# foo.dll.lib
rspfile = "${dllname}.rsp"

link_command = "$python_path $tool_wrapper_path link-wrapper $env False link.exe /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:${dllname}.pdb @$rspfile"
link_command = "$python_path $tool_wrapper_path link-wrapper $env False $link /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:${dllname}.pdb @$rspfile"

# TODO(brettw) support manifests
#manifest_command = "$python_path $tool_wrapper_path manifest-wrapper $env mt.exe -nologo -manifest $manifests -out:${dllname}.manifest"
Expand Down Expand Up @@ -216,7 +225,7 @@ template("msvc_toolchain") {
rspfile = "$binary_output.rsp"
pdbfile = "$binary_output.pdb"

link_command = "$python_path $tool_wrapper_path link-wrapper $env False link.exe /nologo /OUT:$binary_output /PDB:$pdbfile @$rspfile"
link_command = "$python_path $tool_wrapper_path link-wrapper $env False $link /nologo /OUT:$binary_output /PDB:$pdbfile @$rspfile"

# TODO(brettw) support manifests
#manifest_command = "$python_path $tool_wrapper_path manifest-wrapper $env mt.exe -nologo -manifest $manifests -out:{{output}}.manifest"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ enum [!A!] {
''');
setAugmentationContent(r'''
augment enum [!A!] {
one,
two,
}
''');

Expand Down
182 changes: 60 additions & 122 deletions pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,64 +59,25 @@ class DuplicateDefinitionVerifier {
/// Check that there are no members with the same name.
void checkEnum(EnumDeclaration node) {
var fragment = node.declaredElement!;
var augmented = fragment.augmented;
var declarationElement = augmented.declaration;
var declarationElement = fragment.augmented.declaration;
var declarationName = declarationElement.name;

var constructorNames = <String>{};
var instanceGetters = <String, Element>{};
var instanceSetters = <String, Element>{};
var staticGetters = <String, Element>{};
var staticSetters = <String, Element>{};
var elementContext = _getElementContext(declarationElement);
var staticGetters = elementContext.staticGetters;

for (EnumConstantDeclaration constant in node.constants) {
if (constant.name.lexeme == declarationName) {
_errorReporter.atToken(
constant.name,
CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
);
}
_checkDuplicateIdentifier(staticGetters, constant.name,
element: constant.declaredElement!);
_checkValuesDeclarationInEnum(constant.name);
}

for (var member in node.members) {
if (member is ConstructorDeclaration) {
if (member.returnType.name == declarationElement.name) {
var name = member.declaredElement!.name;
if (!constructorNames.add(name)) {
if (name.isEmpty) {
_errorReporter.reportErrorForName(
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
member,
);
} else {
_errorReporter.reportErrorForName(
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
member,
arguments: [name],
);
}
}
}
} else if (member is FieldDeclaration) {
for (var field in member.fields.variables) {
var identifier = field.name;
_checkDuplicateIdentifier(
member.isStatic ? staticGetters : instanceGetters,
identifier,
element: field.declaredElement!,
setterScope: member.isStatic ? staticSetters : instanceSetters,
);
_checkValuesDeclarationInEnum(identifier);
}
} else if (member is MethodDeclaration) {
_checkDuplicateIdentifier(
member.isStatic ? staticGetters : instanceGetters,
member.name,
element: member.declaredElement!,
setterScope: member.isStatic ? staticSetters : instanceSetters,
);
if (!(member.isStatic && member.isSetter)) {
_checkValuesDeclarationInEnum2(member.name);
}
}
}
_checkClassMembers(fragment, node.members);

if (declarationName == 'values') {
_errorReporter.atToken(
Expand All @@ -125,21 +86,6 @@ class DuplicateDefinitionVerifier {
);
}

for (var constant in node.constants) {
if (constant.name.lexeme == declarationName) {
_errorReporter.atToken(
constant.name,
CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
);
}
}

_checkConflictingConstructorAndStatic(
interfaceElement: declarationElement,
staticGetters: staticGetters,
staticSetters: staticSetters,
);

for (var accessor in fragment.accessors) {
var baseName = accessor.displayName;
if (accessor.isStatic) {
Expand Down Expand Up @@ -200,31 +146,14 @@ class DuplicateDefinitionVerifier {

/// Check that there are no members with the same name.
void checkExtension(ExtensionDeclaration node) {
var instanceGetters = <String, Element>{};
var instanceSetters = <String, Element>{};
var staticGetters = <String, Element>{};
var staticSetters = <String, Element>{};
var fragment = node.declaredElement!;
var declarationElement = fragment.augmented.declaration;

for (var member in node.members) {
if (member is FieldDeclaration) {
for (var field in member.fields.variables) {
var identifier = field.name;
_checkDuplicateIdentifier(
member.isStatic ? staticGetters : instanceGetters,
identifier,
element: field.declaredElement!,
setterScope: member.isStatic ? staticSetters : instanceSetters,
);
}
} else if (member is MethodDeclaration) {
_checkDuplicateIdentifier(
member.isStatic ? staticGetters : instanceGetters,
member.name,
element: member.declaredElement!,
setterScope: member.isStatic ? staticSetters : instanceSetters,
);
}
}
var elementContext = _getElementContext(declarationElement);
var instanceGetters = elementContext.instanceGetters;
var instanceSetters = elementContext.instanceSetters;

_checkClassMembers(fragment, node.members);

// Check for local static members conflicting with local instance members.
for (var member in node.members) {
Expand Down Expand Up @@ -404,8 +333,12 @@ class DuplicateDefinitionVerifier {
}

/// Check that there are no members with the same name.
void _checkClassMembers(InterfaceElement element, List<ClassMember> members) {
var declarationElement = element.augmented.declaration;
void _checkClassMembers(
InstanceElement fragment,
List<ClassMember> members,
) {
var declarationElement = fragment.augmented.declaration;

var elementContext = _getElementContext(declarationElement);
var constructorNames = elementContext.constructorNames;
var instanceGetters = elementContext.instanceGetters;
Expand Down Expand Up @@ -446,6 +379,9 @@ class DuplicateDefinitionVerifier {
element: field.declaredElement!,
setterScope: member.isStatic ? staticSetters : instanceSetters,
);
if (fragment is EnumElement) {
_checkValuesDeclarationInEnum(field.name);
}
}
case MethodDeclaration():
_checkDuplicateIdentifier(
Expand All @@ -454,14 +390,21 @@ class DuplicateDefinitionVerifier {
element: member.declaredElement!,
setterScope: member.isStatic ? staticSetters : instanceSetters,
);
if (fragment is EnumElement) {
if (!(member.isStatic && member.isSetter)) {
_checkValuesDeclarationInEnum(member.name);
}
}
}
}

_checkConflictingConstructorAndStatic(
interfaceElement: declarationElement,
staticGetters: staticGetters,
staticSetters: staticSetters,
);
if (declarationElement is InterfaceElement) {
_checkConflictingConstructorAndStatic(
interfaceElement: declarationElement,
staticGetters: staticGetters,
staticSetters: staticSetters,
);
}

// Check for local static members conflicting with local instance members.
// TODO(scheglov): This code is duplicated for enums. But for classes it is
Expand All @@ -474,12 +417,14 @@ class DuplicateDefinitionVerifier {
String name = identifier.lexeme;
if (instanceGetters.containsKey(name) ||
instanceSetters.containsKey(name)) {
String className = declarationElement.displayName;
_errorReporter.atToken(
identifier,
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
arguments: [className, name, className],
);
if (declarationElement is InterfaceElement) {
String className = declarationElement.name;
_errorReporter.atToken(
identifier,
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
arguments: [className, name, className],
);
}
}
}
}
Expand All @@ -489,12 +434,14 @@ class DuplicateDefinitionVerifier {
String name = identifier.lexeme;
if (instanceGetters.containsKey(name) ||
instanceSetters.containsKey(name)) {
String className = declarationElement.name;
_errorReporter.atToken(
identifier,
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
arguments: [className, name, className],
);
if (declarationElement is InterfaceElement) {
String className = declarationElement.name;
_errorReporter.atToken(
identifier,
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
arguments: [className, name, className],
);
}
}
}
}
Expand Down Expand Up @@ -625,18 +572,9 @@ class DuplicateDefinitionVerifier {
}
}

void _checkValuesDeclarationInEnum2(Token name) {
if (name.lexeme == 'values') {
_errorReporter.atToken(
name,
CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM,
);
}
}

_InterfaceElementContext _getElementContext(InterfaceElement element) {
return context._interfaceElementContexts[element] ??=
_InterfaceElementContext();
_InstanceElementContext _getElementContext(InstanceElement element) {
return context._instanceElementContexts[element] ??=
_InstanceElementContext();
}

ExecutableElement? _getInheritedMember(
Expand Down Expand Up @@ -677,12 +615,12 @@ class DuplicateDefinitionVerifier {

/// Information to pass from declarations to augmentations.
class DuplicationDefinitionContext {
final Map<InterfaceElement, _InterfaceElementContext>
_interfaceElementContexts = {};
final Map<InstanceElement, _InstanceElementContext> _instanceElementContexts =
{};
}

/// Information accumulated for a single declaration and its augmentations.
class _InterfaceElementContext {
class _InstanceElementContext {
final Set<String> constructorNames = {};
final Map<String, Element> instanceGetters = {};
final Map<String, Element> instanceSetters = {};
Expand Down
Loading

0 comments on commit be229e0

Please sign in to comment.